Skip to content

Commit 432af1a

Browse files
author
MalavikaSamak
committed
Handle do-while stmts, complex expressions and move warning to appropriate location.
1 parent 66345a4 commit 432af1a

File tree

4 files changed

+45
-42
lines changed

4 files changed

+45
-42
lines changed

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
9999

100100
auto LoopExpr =
101101
[](const ast_matchers::internal::Matcher<Stmt> &InnerMatcher) {
102-
return stmt(anyOf(forStmt(InnerMatcher), whileStmt(InnerMatcher)));
102+
return stmt(anyOf(forStmt(InnerMatcher), whileStmt(InnerMatcher), doStmt(InnerMatcher)));
103103
};
104104

105105
const auto IntegerExpr = ignoringParenImpCasts(integerLiteral());
@@ -141,7 +141,9 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
141141

142142
if (WarnOnSizeOfInLoopTermination) {
143143
Finder->addMatcher(
144-
LoopExpr(has(binaryOperator(has(SizeOfExpr)))).bind("loop-expr"), this);
144+
LoopExpr(hasDescendant(
145+
binaryOperator(allOf(has(SizeOfExpr.bind("sizeof-expr")), isComparisonOperator()))
146+
)).bind("loop-expr"), this);
145147
}
146148

147149
// Detect sizeof(kPtr) where kPtr is 'const char* kPtr = "abc"';
@@ -369,15 +371,16 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
369371
<< E->getSourceRange();
370372
} else if (const auto *E = Result.Nodes.getNodeAs<Stmt>("loop-expr")) {
371373
auto *SizeofArgTy = Result.Nodes.getNodeAs<Type>("sizeof-arg-type");
372-
if (const auto member = dyn_cast<MemberPointerType>(SizeofArgTy)) {
374+
if (const auto member = dyn_cast<MemberPointerType>(SizeofArgTy))
373375
SizeofArgTy = member->getPointeeType().getTypePtr();
374-
}
376+
377+
auto Loc = Result.Nodes.getNodeAs<Expr>("sizeof-expr");
375378

376379
if (const auto type = dyn_cast<ArrayType>(SizeofArgTy)) {
377380
CharUnits sSize = Ctx.getTypeSizeInChars(type->getElementType());
378381
if (!sSize.isOne()) {
379-
diag(E->getBeginLoc(), "suspicious usage of 'sizeof' in the loop")
380-
<< E->getSourceRange();
382+
diag(Loc->getBeginLoc(), "suspicious usage of 'sizeof' in the loop")
383+
<< Loc->getSourceRange();
381384
}
382385
}
383386
} else if (const auto *E = Result.Nodes.getNodeAs<Expr>("sizeof-pointer")) {

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,8 @@ Changes in existing checks
221221

222222
- Improved :doc: `bugprone-sizeof-expression
223223
<clang-tidy/checks/bugprone/bugprone-sizeof-expression>` check.
224-
225-
Introduced WarnOnSizeOfInLoopTermination sub-class to detect misuses of sizeof expression
226-
in loop conditions.
224+
Introduced WarnOnSizeOfInLoopTermination sub-class to detect misuses of sizeof
225+
expression in loop conditions.
227226

228227
Removed checks
229228
^^^^^^^^^^^^^^

clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,8 @@ Options
320320
.. option:: WarnOnSizeOfInLoopTermination
321321

322322
When `true`, the check will warn about incorrect use of sizeof expression
323-
in loop termination condition. The warning triggers if the sizeof expression
324-
appears to be incorrectly used to determine the number of array/buffer elements.
323+
in loop termination condition. The warning triggers if the ``sizeof``
324+
expression appears to be incorrectly used to determine the number of
325+
array/buffer elements.
325326
e.g, ``long arr[10]; for(int i = 0; i < sizeof(arr); i++) { ... }``. Default
326327
is `true`.

clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -173,44 +173,44 @@ struct B {
173173
};
174174

175175
void loop_access_elements(int num, struct B b) {
176-
struct A arr[10];
177-
char buf[20];
178-
179-
// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]
180-
for(int i = 0; i < sizeof(arr); i++) {
181-
struct A a = arr[i];
182-
}
183-
184-
// Loop warning should not trigger here, even though this code is incorrect
185-
// CHECK-MESSAGES: :[[@LINE+2]]:24: warning: suspicious usage of 'sizeof(K)'; did you mean 'K'? [bugprone-sizeof-expression]
186-
// CHECK-MESSAGES: :[[@LINE+1]]:34: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator [bugprone-sizeof-expression]
187-
for(int i = 0; i < sizeof(10)/sizeof(A); i++) {
188-
struct A a = arr[i];
189-
}
176+
struct A arr[10];
177+
char buf[20];
178+
179+
// CHECK-MESSAGES: :[[@LINE+1]]:22: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]
180+
for(int i = 0; i < sizeof(arr); i++) {
181+
struct A a = arr[i];
182+
}
183+
184+
// Loop warning should not trigger here, even though this code is incorrect
185+
// CHECK-MESSAGES: :[[@LINE+2]]:22: warning: suspicious usage of 'sizeof(K)'; did you mean 'K'? [bugprone-sizeof-expression]
186+
// CHECK-MESSAGES: :[[@LINE+1]]:32: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator [bugprone-sizeof-expression]
187+
for(int i = 0; i < sizeof(10)/sizeof(A); i++) {
188+
struct A a = arr[i];
189+
}
190190

191-
// Should not warn here
192-
for(int i = 0; i < sizeof(arr)/sizeof(A); i++) {}
191+
// Should not warn here
192+
for(int i = 0; i < sizeof(arr)/sizeof(A); i++) {}
193193

194-
// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]
195-
for(int j = 0; j < sizeof(b.a.array); j++) {}
194+
// CHECK-MESSAGES: :[[@LINE+1]]:22: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]
195+
for(int j = 0; j < sizeof(b.a.array); j++) {}
196196

197-
// Should not warn here
198-
for(int i = 0; i < sizeof(buf); i++) {}
197+
// Should not warn here
198+
for(int i = 0; i < sizeof(buf); i++) {}
199199

200-
int i = 0;
201-
// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]
202-
while(i <= sizeof(arr)) {i++;}
200+
int i = 0;
201+
// CHECK-MESSAGES: :[[@LINE+1]]:14: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]
202+
while(i <= sizeof(arr)) {i++;}
203203

204-
i = 0;
205-
do {
206-
i++;
207-
} while(i <= sizeof(arr));
204+
i = 0;
205+
do {
206+
i++;
207+
// CHECK-MESSAGES: :[[@LINE+1]]:16: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]
208+
} while(i <= sizeof(arr));
209+
210+
// CHECK-MESSAGES: :[[@LINE+1]]:29: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]
211+
for(int i = 0, j = 0; i < sizeof(arr) && j < sizeof(buf); i++, j++) {}
208212
}
209213

210-
// Add cases for while loop
211-
212-
// Add cases for do-while loop
213-
214214
template <int T>
215215
int Foo() { int A[T]; return sizeof(T); }
216216
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of 'sizeof(K)'

0 commit comments

Comments
 (0)