Skip to content

Commit 5e83b26

Browse files
authored
[clang-tidy] Keep parentheses when replacing index access in sizeof calls (#82166)
Fixes #56021.
1 parent 536d78c commit 5e83b26

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -706,13 +706,17 @@ void LoopConvertCheck::doConversion(
706706
ReplaceText = Usage.Kind == Usage::UK_MemberThroughArrow
707707
? VarNameOrStructuredBinding + "."
708708
: VarNameOrStructuredBinding;
709-
auto Parents = Context->getParents(*Usage.Expression);
709+
const DynTypedNodeList Parents = Context->getParents(*Usage.Expression);
710710
if (Parents.size() == 1) {
711711
if (const auto *Paren = Parents[0].get<ParenExpr>()) {
712712
// Usage.Expression will be replaced with the new index variable,
713713
// and parenthesis around a simple DeclRefExpr can always be
714-
// removed.
715-
Range = Paren->getSourceRange();
714+
// removed except in case of a `sizeof` operator call.
715+
const DynTypedNodeList GrandParents = Context->getParents(*Paren);
716+
if (GrandParents.size() != 1 ||
717+
GrandParents[0].get<UnaryExprOrTypeTraitExpr>() == nullptr) {
718+
Range = Paren->getSourceRange();
719+
}
716720
} else if (const auto *UOP = Parents[0].get<UnaryOperator>()) {
717721
// If we are taking the address of the loop variable, then we must
718722
// not use a copy, as it would mean taking the address of the loop's

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ Changes in existing checks
170170
`AllowStringArrays` option, enabling the exclusion of array types with deduced
171171
length initialized from string literals.
172172

173+
- Improved :doc:`modernize-loop-convert
174+
<clang-tidy/checks/modernize/loop-convert>` check by ensuring that fix-its
175+
don't remove parentheses used in ``sizeof`` calls when they have array index
176+
accesses as arguments.
177+
173178
- Improved :doc:`modernize-use-override
174179
<clang-tidy/checks/modernize/use-override>` check to also remove any trailing
175180
whitespace when deleting the ``virtual`` keyword.

clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,19 @@ void f() {
8888
// CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);
8989
// CHECK-FIXES-NEXT: Sum += I + 2;
9090

91+
int Matrix[N][12];
92+
unsigned size = 0;
93+
for (int I = 0; I < N; ++I) {
94+
size += sizeof(Matrix[I]);
95+
size += sizeof Matrix[I];
96+
size += sizeof((Matrix[I]));
97+
}
98+
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
99+
// CHECK-FIXES: for (auto & I : Matrix)
100+
// CHECK-FIXES-NEXT: size += sizeof(I);
101+
// CHECK-FIXES-NEXT: size += sizeof I;
102+
// CHECK-FIXES-NEXT: size += sizeof(I);
103+
91104
Val Teas[N];
92105
for (int I = 0; I < N; ++I) {
93106
Teas[I].g();

0 commit comments

Comments
 (0)