From cae3b70cebc1b7b762a8b466cafca2d4189e72a7 Mon Sep 17 00:00:00 2001 From: Chris Hamilton Date: Thu, 22 Apr 2021 15:39:36 -0500 Subject: [PATCH] [PR49761] Fix variadic arg handling in matcher Mishandling of variadic arguments in a function call caused a crash (runtime assert fail) in bugprone-infinite-loop tidy checker. Fix is to limit argument matching to the lesser of the number of variadic params in the prototype or the number of actual args in the call. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D101108 --- .../checkers/bugprone-infinite-loop.cpp | 15 +++++++++++++++ clang/include/clang/ASTMatchers/ASTMatchers.h | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp index 8bd4df7cd844..0b1baf04fee2 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp @@ -386,3 +386,18 @@ void evaluatable(bool CondVar) { do { } while (false && CondVar); } + +struct logger { + void (*debug)(struct logger *, const char *, ...); +}; + +int foo(void) { + struct logger *pl = 0; + int iterator = 0; + while (iterator < 10) { + char *l_tmp_msg = 0; + pl->debug(pl, "%d: %s\n", iterator, l_tmp_msg); + iterator++; + } + return 0; +} diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 33f57b755941..fbf98d9f7af0 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4757,8 +4757,11 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType, int ParamIndex = 0; bool Matched = false; + unsigned NumArgs = Node.getNumArgs(); + if (FProto && FProto->isVariadic()) + NumArgs = std::min(NumArgs, FProto->getNumParams()); - for (; ArgIndex < Node.getNumArgs(); ++ArgIndex, ++ParamIndex) { + for (; ArgIndex < NumArgs; ++ArgIndex, ++ParamIndex) { BoundNodesTreeBuilder ArgMatches(*Builder); if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()), Finder, &ArgMatches)) {