Skip to content

Commit 84842f4

Browse files
authored
[clang-tidy] bugprone-assert-side-effect can detect side effect from non-const reference parameters (#84095)
Fixes: #84092
1 parent 59a9201 commit 84842f4

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,26 @@ AST_MATCHER_P2(Expr, hasSideEffect, bool, CheckFunctionCalls,
6060
}
6161

6262
if (const auto *CExpr = dyn_cast<CallExpr>(E)) {
63-
bool Result = CheckFunctionCalls;
63+
if (!CheckFunctionCalls)
64+
return false;
6465
if (const auto *FuncDecl = CExpr->getDirectCallee()) {
6566
if (FuncDecl->getDeclName().isIdentifier() &&
6667
IgnoredFunctionsMatcher.matches(*FuncDecl, Finder,
6768
Builder)) // exceptions come here
68-
Result = false;
69-
else if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FuncDecl))
70-
Result &= !MethodDecl->isConst();
69+
return false;
70+
for (size_t I = 0; I < FuncDecl->getNumParams(); I++) {
71+
const ParmVarDecl *P = FuncDecl->getParamDecl(I);
72+
const Expr *ArgExpr =
73+
I < CExpr->getNumArgs() ? CExpr->getArg(I) : nullptr;
74+
const QualType PT = P->getType().getCanonicalType();
75+
if (ArgExpr && !ArgExpr->isXValue() && PT->isReferenceType() &&
76+
!PT.getNonReferenceType().isConstQualified())
77+
return true;
78+
}
79+
if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FuncDecl))
80+
return !MethodDecl->isConst();
7181
}
72-
return Result;
82+
return true;
7383
}
7484

7585
return isa<CXXNewExpr>(E) || isa<CXXDeleteExpr>(E) || isa<CXXThrowExpr>(E);

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ New check aliases
128128
Changes in existing checks
129129
^^^^^^^^^^^^^^^^^^^^^^^^^^
130130

131+
- Improved :doc:`bugprone-assert-side-effect
132+
<clang-tidy/checks/bugprone/assert-side-effect>` check by detecting side
133+
effect from calling a method with non-const reference parameters.
134+
131135
- Improved :doc:`bugprone-non-zero-enum-to-bool-conversion
132136
<clang-tidy/checks/bugprone/non-zero-enum-to-bool-conversion>` check by
133137
eliminating false positives resulting from direct usage of bitwise operators

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,27 @@ int main() {
108108

109109
return 0;
110110
}
111+
112+
namespace parameter_anaylysis {
113+
114+
struct S {
115+
bool value(int) const;
116+
bool leftValueRef(int &) const;
117+
bool constRef(int const &) const;
118+
bool rightValueRef(int &&) const;
119+
};
120+
121+
void foo() {
122+
S s{};
123+
int i = 0;
124+
assert(s.value(0));
125+
assert(s.value(i));
126+
assert(s.leftValueRef(i));
127+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
128+
assert(s.constRef(0));
129+
assert(s.constRef(i));
130+
assert(s.rightValueRef(0));
131+
assert(s.rightValueRef(static_cast<int &&>(i)));
132+
}
133+
134+
} // namespace parameter_anaylysis

0 commit comments

Comments
 (0)