Skip to content

Commit e89602b

Browse files
committed
[clang-tidy] Fix readability-suspicious-call-argument crash for arguments without name-like identifier
As originally reported by @steakhal in http://github.com/llvm/llvm-project/issues/54074, the name extraction logic of `readability-suspicious-call-argument` crashes if the argument passed to a function was a function call to a non-trivially named entity (e.g. an operator). Fixed this crash case by ignoring such constructs and considering them as having no name. Reviewed By: aaron.ballman, steakhal Differential Revision: http://reviews.llvm.org/D120555 (Cherry-picked from commit 416e689)
1 parent 1f7e8b1 commit e89602b

File tree

3 files changed

+48
-10
lines changed

3 files changed

+48
-10
lines changed

clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -711,23 +711,28 @@ void SuspiciousCallArgumentCheck::setArgNamesAndTypes(
711711

712712
for (std::size_t I = InitialArgIndex, J = MatchedCallExpr->getNumArgs();
713713
I < J; ++I) {
714+
assert(ArgTypes.size() == I - InitialArgIndex &&
715+
ArgNames.size() == ArgTypes.size() &&
716+
"Every iteration must put an element into the vectors!");
717+
714718
if (const auto *ArgExpr = dyn_cast<DeclRefExpr>(
715719
MatchedCallExpr->getArg(I)->IgnoreUnlessSpelledInSource())) {
716720
if (const auto *Var = dyn_cast<VarDecl>(ArgExpr->getDecl())) {
717721
ArgTypes.push_back(Var->getType());
718722
ArgNames.push_back(Var->getName());
719-
} else if (const auto *FCall =
720-
dyn_cast<FunctionDecl>(ArgExpr->getDecl())) {
721-
ArgTypes.push_back(FCall->getType());
722-
ArgNames.push_back(FCall->getName());
723-
} else {
724-
ArgTypes.push_back(QualType());
725-
ArgNames.push_back(StringRef());
723+
continue;
724+
}
725+
if (const auto *FCall = dyn_cast<FunctionDecl>(ArgExpr->getDecl())) {
726+
if (FCall->getNameInfo().getName().isIdentifier()) {
727+
ArgTypes.push_back(FCall->getType());
728+
ArgNames.push_back(FCall->getName());
729+
continue;
730+
}
726731
}
727-
} else {
728-
ArgTypes.push_back(QualType());
729-
ArgNames.push_back(StringRef());
730732
}
733+
734+
ArgTypes.push_back(QualType());
735+
ArgNames.push_back(StringRef());
731736
}
732737
}
733738

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,10 @@ Changes in existing checks
352352
return statements associated with ``case``, ``default`` and labeled
353353
statements.
354354

355+
- Fixed a crash in :doc:`readability-suspicious-call-argument
356+
<clang-tidy/checks/readability-suspicious-call-argument>` related to passing
357+
arguments that refer to program elements without a trivial identifier.
358+
355359
Removed checks
356360
^^^^^^^^^^^^^^
357361

clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,3 +485,32 @@ int main() {
485485

486486
return 0;
487487
}
488+
489+
namespace Issue_54074 {
490+
491+
class T {};
492+
using OperatorTy = int(const T &, const T &);
493+
int operator-(const T &, const T &);
494+
495+
template <typename U>
496+
struct Wrap {
497+
Wrap(U);
498+
};
499+
500+
template <typename V>
501+
void wrapTaker(V, Wrap<OperatorTy>);
502+
503+
template <typename V>
504+
void wrapTaker(V aaaaa, V bbbbb, Wrap<OperatorTy>);
505+
506+
void test() {
507+
wrapTaker(0, operator-);
508+
// NO-WARN. No crash!
509+
510+
int aaaaa = 4, bbbbb = 8;
511+
wrapTaker(bbbbb, aaaaa, operator-);
512+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'bbbbb' (passed to 'aaaaa') looks like it might be swapped with the 2nd, 'aaaaa' (passed to 'bbbbb')
513+
// CHECK-MESSAGES: :[[@LINE-9]]:6: note: in the call to 'wrapTaker<int>', declared here
514+
}
515+
516+
} // namespace Issue_54074

0 commit comments

Comments
 (0)