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 --- 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 @@ 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 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4757,8 +4757,11 @@ 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)) {