Index: clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp =================================================================== --- clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp +++ clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "ProTypeReinterpretCastCheck.h" +#include "Suppression.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -21,7 +22,8 @@ if (!getLangOpts().CPlusPlus) return; - Finder->addMatcher(cxxReinterpretCastExpr().bind("cast"), this); + std::vector Rules{"type", "type.1", "cppcoreguidelines-pro-type-reinterpret-cast"}; + Finder->addMatcher(cxxReinterpretCastExpr(unless(isSuppressed(Rules))).bind("cast"), this); } void ProTypeReinterpretCastCheck::check( Index: clang-tidy/cppcoreguidelines/Suppression.h =================================================================== --- /dev/null +++ clang-tidy/cppcoreguidelines/Suppression.h @@ -0,0 +1,67 @@ +//===--- Suppression.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_SUPPRESSION_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SUPPRESSION_H + +namespace clang { +namespace tidy { +namespace cppcoreguidelines { + +const ast_matchers::internal::VariadicDynCastAllOfMatcher + attributedStmt; + +AST_MATCHER(Decl, hasAttrs) { return Node.hasAttrs(); } + +// If called on a Decl, assumes that hasAttrs() is true. +AST_POLYMORPHIC_MATCHER_P_OVERLOAD( + hasSuppressAttr, AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, AttributedStmt), + std::vector, Rules, 0) { + llvm::outs() << "hasSuppressAttr called\n"; + if (const auto *Suppress = + getSpecificAttr(Node.getAttrs())) { + for (const auto &Rule : Rules) { + auto It = std::find_if(Suppress->rules_begin(), Suppress->rules_end(), + [Rule](const std::string &R) { + llvm::outs() << "Rule " << R << "\n"; + return R == Rule; + }); + if (It != Suppress->rules_end()) + return true; + } + } + return false; +} + +// If called on a Decl, assumes that hasAttrs() is true. +AST_POLYMORPHIC_MATCHER_P_OVERLOAD( + hasSuppressAttr, AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, AttributedStmt), + StringRef, Rule, 1) { + std::vector Rules(1, Rule); + return ast_matchers::internal::Matcher(hasSuppressAttr(Rules)) + .matches(Node, Finder, Builder); +} + +/// Checks if any ancestor has a [[clang::suppress(rule, ...)]] attribute with +/// one of the given Rules. +AST_POLYMORPHIC_MATCHER_P(isSuppressed, + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt), + std::vector, Rules) { + using namespace clang::ast_matchers; + return ast_matchers::internal::Matcher( + anyOf(hasAncestor(attributedStmt(hasSuppressAttr(Rules))), + hasAncestor(decl(hasAttrs(), hasSuppressAttr(Rules))))) + .matches(Node, Finder, Builder); +} + +} // namespace cppcoreguidelines +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SUPPRESSION_H Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst =================================================================== --- docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst +++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst @@ -11,3 +11,7 @@ This rule is part of the "Type safety" profile of the C++ Core Guidelines, see https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-reinterpretcast. + +Warnings of this check can be suppressed by using the C++11 attribute +``[[clang::suppress("tag")]]`` with a tag of either "type", "type.1" or +"cppcoreguidelines-pro-type-reinterpret-cast". Index: test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp =================================================================== --- test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp +++ test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp @@ -4,3 +4,14 @@ void *j; void f() { j = reinterpret_cast(i); } // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast] + +[[clang::suppress("cppcoreguidelines-pro-type-reinterpret-cast")]] +void suppress_f() { j = reinterpret_cast(i); } + +void suppress_f2() { + [[clang::suppress("type")]] j = reinterpret_cast(i); + [[clang::suppress("type.1")]] { + i = 1; + j = reinterpret_cast(i); + } +}