Skip to content

Commit c95d581

Browse files
authored
[clang-tidy] bugprone-assert-side-effect non-const operator methods (#71974)
With this PR, `bugprone-assert-side-effect` reports non-const calls to `<<` and `>>` operators and does no longer consider any const operator calls to have side effects. E.g. the following snippet is now reported and was previously not: ``` std::stringstream ss; assert(ss << 1); ``` The following snippet was previously a false-positive and is not reported anymore: ``` struct { int operator+=(int i) const { return i; } } t; assert(t += 1); ```
1 parent aa4e34b commit c95d581

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,18 @@ AST_MATCHER_P2(Expr, hasSideEffect, bool, CheckFunctionCalls,
4141
}
4242

4343
if (const auto *OpCallExpr = dyn_cast<CXXOperatorCallExpr>(E)) {
44+
if (const auto *MethodDecl =
45+
dyn_cast_or_null<CXXMethodDecl>(OpCallExpr->getDirectCallee()))
46+
if (MethodDecl->isConst())
47+
return false;
48+
4449
OverloadedOperatorKind OpKind = OpCallExpr->getOperator();
4550
return OpKind == OO_Equal || OpKind == OO_PlusEqual ||
4651
OpKind == OO_MinusEqual || OpKind == OO_StarEqual ||
4752
OpKind == OO_SlashEqual || OpKind == OO_AmpEqual ||
4853
OpKind == OO_PipeEqual || OpKind == OO_CaretEqual ||
4954
OpKind == OO_LessLessEqual || OpKind == OO_GreaterGreaterEqual ||
55+
OpKind == OO_LessLess || OpKind == OO_GreaterGreater ||
5056
OpKind == OO_PlusPlus || OpKind == OO_MinusMinus ||
5157
OpKind == OO_PercentEqual || OpKind == OO_New ||
5258
OpKind == OO_Delete || OpKind == OO_Array_New ||

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ Changes in existing checks
212212
<clang-tidy/checks/abseil/string-find-startswith>` check to also consider
213213
``std::basic_string_view`` in addition to ``std::basic_string`` by default.
214214

215+
- Improved :doc:`bugprone-assert-side-effect
216+
<clang-tidy/checks/bugprone/assert-side-effect>` check to report usage of
217+
non-const ``<<`` and ``>>`` operators in assertions and fixed some false-positives
218+
with const operators.
219+
215220
- Improved :doc:`bugprone-dangling-handle
216221
<clang-tidy/checks/bugprone/dangling-handle>` check to support functional
217222
casting during type conversions at variable initialization, now with improved

clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,27 @@ int main() {
8484
msvc_assert(mc2 = mc);
8585
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in msvc_assert() condition discarded in release builds
8686

87+
struct OperatorTest {
88+
int operator<<(int i) const { return i; }
89+
int operator<<(int i) { return i; }
90+
int operator+=(int i) const { return i; }
91+
int operator+=(int i) { return i; }
92+
};
93+
94+
const OperatorTest const_instance;
95+
assert(const_instance << 1);
96+
assert(const_instance += 1);
97+
98+
OperatorTest non_const_instance;
99+
assert(static_cast<const OperatorTest>(non_const_instance) << 1);
100+
assert(static_cast<const OperatorTest>(non_const_instance) += 1);
101+
assert(non_const_instance << 1);
102+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
103+
assert(non_const_instance += 1);
104+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
105+
106+
assert(5<<1);
107+
assert(5>>1);
108+
87109
return 0;
88110
}

0 commit comments

Comments
 (0)