diff options
Diffstat (limited to 'clang-tools-extra/clang-tidy/cppcoreguidelines')
4 files changed, 114 insertions, 4 deletions
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt index cd81c4f6147..b2c2bdf97a3 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt @@ -7,6 +7,7 @@ add_clang_library(clangTidyCppCoreGuidelinesModule ProTypeReinterpretCastCheck.cpp ProTypeStaticCastDowncastCheck.cpp ProTypeUnionAccessCheck.cpp + ProTypeVarargCheck.cpp LINK_LIBS clangAST @@ -14,7 +15,6 @@ add_clang_library(clangTidyCppCoreGuidelinesModule clangBasic clangLex clangTidy - clangTidyCERTModule clangTidyMiscModule clangTidyUtils clangTooling diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp index 3d517902660..9929d66e780 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -10,13 +10,13 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" -#include "../cert/VariadicFunctionDefCheck.h" #include "../misc/AssignOperatorSignatureCheck.h" #include "ProBoundsPointerArithmeticCheck.h" #include "ProTypeConstCastCheck.h" #include "ProTypeReinterpretCastCheck.h" #include "ProTypeStaticCastDowncastCheck.h" #include "ProTypeUnionAccessCheck.h" +#include "ProTypeVarargCheck.h" namespace clang { namespace tidy { @@ -30,14 +30,14 @@ public: "cppcoreguidelines-pro-bounds-pointer-arithmetic"); CheckFactories.registerCheck<ProTypeConstCastCheck>( "cppcoreguidelines-pro-type-const-cast"); - CheckFactories.registerCheck<VariadicFunctionDefCheck>( - "cppcoreguidelines-pro-type-vararg-def"); CheckFactories.registerCheck<ProTypeReinterpretCastCheck>( "cppcoreguidelines-pro-type-reinterpret-cast"); CheckFactories.registerCheck<ProTypeStaticCastDowncastCheck>( "cppcoreguidelines-pro-type-static-cast-downcast"); CheckFactories.registerCheck<ProTypeUnionAccessCheck>( "cppcoreguidelines-pro-type-union-access"); + CheckFactories.registerCheck<ProTypeVarargCheck>( + "cppcoreguidelines-pro-type-vararg"); CheckFactories.registerCheck<misc::AssignOperatorSignatureCheck>( "cppcoreguidelines-c-copy-assignment-signature"); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp new file mode 100644 index 00000000000..526016eadd9 --- /dev/null +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp @@ -0,0 +1,76 @@ +//===--- ProTypeVarargCheck.cpp - clang-tidy-------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ProTypeVarargCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { + +const internal::VariadicDynCastAllOfMatcher<Stmt, VAArgExpr> vAArgExpr; + +void ProTypeVarargCheck::registerMatchers(MatchFinder *Finder) { + if (!getLangOpts().CPlusPlus) + return; + + Finder->addMatcher(vAArgExpr().bind("va_use"), this); + + Finder->addMatcher( + callExpr(callee(functionDecl(isVariadic()))) + .bind("callvararg"), + this); +} + +static bool hasSingleVariadicArgumentWithValue(const CallExpr *C, uint64_t I) { + const auto *FDecl = dyn_cast<FunctionDecl>(C->getCalleeDecl()); + if (!FDecl) + return false; + + auto N = FDecl->getNumParams(); // Number of parameters without '...' + if (C->getNumArgs() != N + 1) + return false; // more/less than one argument passed to '...' + + const auto *IntLit = + dyn_cast<IntegerLiteral>(C->getArg(N)->IgnoreParenImpCasts()); + if (!IntLit) + return false; + + if (IntLit->getValue() != I) + return false; + + return true; +} + +void ProTypeVarargCheck::check(const MatchFinder::MatchResult &Result) { + if (const auto *Matched = Result.Nodes.getNodeAs<CallExpr>("callvararg")) { + if (hasSingleVariadicArgumentWithValue(Matched, 0)) + return; + diag(Matched->getExprLoc(), "do not call c-style vararg functions"); + } + + if (const auto *Matched = Result.Nodes.getNodeAs<Expr>("va_use")) { + diag(Matched->getExprLoc(), + "do not use va_start/va_arg to define c-style vararg functions; " + "use variadic templates instead"); + } + + if (const auto *Matched = Result.Nodes.getNodeAs<VarDecl>("va_list")) { + auto SR = Matched->getSourceRange(); + if (SR.isInvalid()) + return; // some implicitly generated builtins take va_list + diag(SR.getBegin(), "do not declare variables of type va_list; " + "use variadic templates instead"); + } +} + +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h new file mode 100644 index 00000000000..fd1f9bfe403 --- /dev/null +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h @@ -0,0 +1,34 @@ +//===--- ProTypeVarargCheck.h - clang-tidy--------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_VARARG_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_VARARG_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { + +/// This check flags all calls to c-style variadic functions and all use +/// of va_arg. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-type-vararg.html +class ProTypeVarargCheck : public ClangTidyCheck { +public: + ProTypeVarargCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_VARARG_H |