Author: Felix Berger Date: 2021-12-15T12:35:07-05:00 New Revision: a1b1c23a3b5f2cbe38e90140227bb38a7783e574
URL: https://github.com/llvm/llvm-project/commit/a1b1c23a3b5f2cbe38e90140227bb38a7783e574 DIFF: https://github.com/llvm/llvm-project/commit/a1b1c23a3b5f2cbe38e90140227bb38a7783e574.diff LOG: [clang] ASTMatchers: Fix out-of-bounds access in foreachArgumentWithParamType. The matcher crashes when a variadic function pointer is invoked because the FunctionProtoType has fewer parameters than arguments. Matching of non-variadic arguments now works. Differential Revision: https://reviews.llvm.org/D114559 Reviewed-by: sammccall Added: Modified: clang/include/clang/ASTMatchers/ASTMatchers.h clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 5221d05477d0e..9f0b363ad5468 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4886,7 +4886,7 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType, // This test is cheaper compared to the big matcher in the next if. // Therefore, please keep this order. - if (FProto) { + if (FProto && FProto->getNumParams() > ParamIndex) { QualType ParamType = FProto->getParamType(ParamIndex); if (ParamMatcher.matches(ParamType, Finder, &ParamMatches)) { Result.addMatch(ParamMatches); diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index e6ddf200c369c..7f4dc3b05d95c 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1094,6 +1094,31 @@ TEST(ForEachArgumentWithParamType, MatchesMemberFunctionPtrCalls) { S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg"))); } +TEST(ForEachArgumentWithParamType, MatchesVariadicFunctionPtrCalls) { + StatementMatcher ArgumentY = + declRefExpr(to(varDecl(hasName("y")))).bind("arg"); + TypeMatcher IntType = qualType(builtinType()).bind("type"); + StatementMatcher CallExpr = + callExpr(forEachArgumentWithParamType(ArgumentY, IntType)); + + StringRef S = R"cpp( + void fcntl(int fd, int cmd, ...) {} + + template <typename Func> + void f(Func F) { + int y = 42; + F(y, 1, 3); + } + + void g() { f(fcntl); } + )cpp"; + + EXPECT_TRUE(matchAndVerifyResultTrue( + S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type"))); + EXPECT_TRUE(matchAndVerifyResultTrue( + S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg"))); +} + TEST(QualType, hasCanonicalType) { EXPECT_TRUE(notMatches("typedef int &int_ref;" "int a;" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits