11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 using namespace clang::ast_matchers;
19 const internal::VariadicDynCastAllOfMatcher<Stmt, VAArgExpr>
vAArgExpr;
21 void ProTypeVarargCheck::registerMatchers(MatchFinder *
Finder) {
22 if (!getLangOpts().CPlusPlus)
25 Finder->addMatcher(
vAArgExpr().bind(
"va_use"),
this);
28 callExpr(callee(functionDecl(isVariadic())))
34 const auto *FDecl = dyn_cast<FunctionDecl>(C->getCalleeDecl());
38 auto N = FDecl->getNumParams();
39 if (C->getNumArgs() != N + 1)
43 dyn_cast<IntegerLiteral>(C->getArg(N)->IgnoreParenImpCasts());
47 if (IntLit->getValue() != I)
53 void ProTypeVarargCheck::check(
const MatchFinder::MatchResult &
Result) {
54 if (
const auto *Matched = Result.Nodes.getNodeAs<CallExpr>(
"callvararg")) {
57 diag(Matched->getExprLoc(),
"do not call c-style vararg functions");
60 if (
const auto *Matched = Result.Nodes.getNodeAs<Expr>(
"va_use")) {
61 diag(Matched->getExprLoc(),
62 "do not use va_start/va_arg to define c-style vararg functions; "
63 "use variadic templates instead");
66 if (
const auto *Matched = Result.Nodes.getNodeAs<VarDecl>(
"va_list")) {
67 auto SR = Matched->getSourceRange();
70 diag(SR.getBegin(),
"do not declare variables of type va_list; "
71 "use variadic templates instead");
const internal::VariadicDynCastAllOfMatcher< Stmt, VAArgExpr > vAArgExpr
std::unique_ptr< ast_matchers::MatchFinder > Finder
static bool hasSingleVariadicArgumentWithValue(const CallExpr *C, uint64_t I)