Skip to content

Commit 932f0de

Browse files
authored
[clang-tidy] fix crash due to assumed callee in min-max-use-initializer-list (#91992)
Previously, the call to `findArgs` for a `CallExpr` inside of a `min` or `max` call would call `findArgs` before checking if the argument is a call to `min` or `max`, which is what `findArgs` is expecting. The fix moves the name checking before the call to `findArgs`, such that only a `min` or `max` function call is used as an argument. Fixes #91982 Fixes #92249
1 parent 8987369 commit 932f0de

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,17 @@ generateReplacements(const MatchFinder::MatchResult &Match,
129129
continue;
130130
}
131131

132+
// if the nested call is not the same as the top call
133+
if (InnerCall->getDirectCallee()->getQualifiedNameAsString() !=
134+
TopCall->getDirectCallee()->getQualifiedNameAsString())
135+
continue;
136+
132137
const FindArgsResult InnerResult = findArgs(InnerCall);
133138

134139
// if the nested call doesn't have arguments skip it
135140
if (!InnerResult.First || !InnerResult.Last)
136141
continue;
137142

138-
// if the nested call is not the same as the top call
139-
if (InnerCall->getDirectCallee()->getQualifiedNameAsString() !=
140-
TopCall->getDirectCallee()->getQualifiedNameAsString())
141-
continue;
142-
143143
// if the nested call doesn't have the same compare function
144144
if ((Result.Compare || InnerResult.Compare) &&
145145
!utils::areStatementsIdentical(Result.Compare, InnerResult.Compare,

clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,27 @@ B maxTT2 = std::max(B(), std::max(B(), B()));
300300
B maxTT3 = std::max(B(), std::max(B(), B()), [](const B &lhs, const B &rhs) { return lhs.a[0] < rhs.a[0]; });
301301
// CHECK-FIXES: B maxTT3 = std::max(B(), std::max(B(), B()), [](const B &lhs, const B &rhs) { return lhs.a[0] < rhs.a[0]; });
302302

303+
struct GH91982 {
304+
int fun0Args();
305+
int fun1Arg(int a);
306+
int fun2Args(int a, int b);
307+
int fun3Args(int a, int b, int c);
308+
int fun4Args(int a, int b, int c, int d);
309+
310+
int foo() {
311+
return std::max(
312+
fun0Args(),
313+
std::max(fun1Arg(0),
314+
std::max(fun2Args(0, 1),
315+
std::max(fun3Args(0, 1, 2), fun4Args(0, 1, 2, 3)))));
316+
// CHECK-MESSAGES: :[[@LINE-5]]:12: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list]
317+
// CHECK-FIXES: return std::max(
318+
// CHECK-FIXES-NEXT: {fun0Args(),
319+
// CHECK-FIXES-NEXT: fun1Arg(0),
320+
// CHECK-FIXES-NEXT: fun2Args(0, 1),
321+
// CHECK-FIXES-NEXT: fun3Args(0, 1, 2), fun4Args(0, 1, 2, 3)});
322+
}
323+
};
303324

304325
} // namespace
305326

0 commit comments

Comments
 (0)