flx created this revision. flx requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D114559 Files: clang/include/clang/ASTMatchers/ASTMatchers.h clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1094,6 +1094,31 @@ 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;" Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4885,7 +4885,7 @@ // 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);
Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1094,6 +1094,31 @@ 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;" Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4885,7 +4885,7 @@ // 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);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits