Index: clang-tidy/ClangTidy.cpp =================================================================== --- clang-tidy/ClangTidy.cpp +++ clang-tidy/ClangTidy.cpp @@ -286,6 +286,7 @@ I != E; ++I) { std::unique_ptr Module(I->instantiate()); Module->addCheckFactories(*CheckFactories); + Module->addWarningCheckAliases(Context.WarningCheckAliases); } } @@ -397,6 +398,10 @@ CheckNames.push_back(CheckFactory.first); } + for (const auto &Alias : Context.WarningCheckAliases) + if (Context.isCheckEnabled(Alias.second)) + CheckNames.push_back(Alias.second); + for (const auto &AnalyzerCheck : getCheckersControlList(Context)) CheckNames.push_back(AnalyzerCheckNamePrefix + AnalyzerCheck.first); @@ -492,6 +497,13 @@ if (Opts.ExtraArgs) AdjustedArgs.insert(AdjustedArgs.end(), Opts.ExtraArgs->begin(), Opts.ExtraArgs->end()); + + for (const auto &Alias : Context.WarningCheckAliases) + if (Context.isCheckEnabled(Alias.second)) + AdjustedArgs.push_back( + "-W" + + DiagnosticIDs::getWarningOptionForDiag(Alias.first).str()); + return AdjustedArgs; }; Index: clang-tidy/ClangTidyDiagnosticConsumer.h =================================================================== --- clang-tidy/ClangTidyDiagnosticConsumer.h +++ clang-tidy/ClangTidyDiagnosticConsumer.h @@ -17,6 +17,7 @@ #include "clang/Tooling/Refactoring.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Regex.h" #include "llvm/Support/Timer.h" @@ -186,6 +187,8 @@ return CurrentBuildDirectory; } + llvm::DenseMap WarningCheckAliases; + private: // Calls setDiagnosticsEngine() and storeError(). friend class ClangTidyDiagnosticConsumer; Index: clang-tidy/ClangTidyDiagnosticConsumer.cpp =================================================================== --- clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -374,9 +374,15 @@ StringRef WarningOption = Context.DiagEngine->getDiagnosticIDs()->getWarningOptionForDiag( Info.getID()); - std::string CheckName = !WarningOption.empty() - ? ("clang-diagnostic-" + WarningOption).str() - : Context.getCheckName(Info.getID()).str(); + auto Alias = Context.WarningCheckAliases.find(Info.getID()); + std::string CheckName; + if (Alias != Context.WarningCheckAliases.end() && + Context.isCheckEnabled(Alias->second)) + CheckName = Alias->second; + else + CheckName = !WarningOption.empty() + ? ("clang-diagnostic-" + WarningOption).str() + : Context.getCheckName(Info.getID()).str(); if (CheckName.empty()) { // This is a compiler diagnostic without a warning option. Assign check Index: clang-tidy/ClangTidyModule.h =================================================================== --- clang-tidy/ClangTidyModule.h +++ clang-tidy/ClangTidyModule.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYMODULE_H #include "ClangTidy.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" #include #include @@ -89,6 +90,11 @@ /// belonging to this module. virtual void addCheckFactories(ClangTidyCheckFactories &CheckFactories) = 0; + /// \brief Implement this function in order to register all warning-check + /// aliases belonging to this module. + virtual void addWarningCheckAliases( + llvm::DenseMap &WarningCheckAliases) {} + /// \brief Gets default options for checks defined in this module. virtual ClangTidyOptions getModuleOptions(); }; Index: clang-tidy/cert/CERTTidyModule.cpp =================================================================== --- clang-tidy/cert/CERTTidyModule.cpp +++ clang-tidy/cert/CERTTidyModule.cpp @@ -26,6 +26,7 @@ #include "StrToNumCheck.h" #include "ThrownExceptionTypeCheck.h" #include "VariadicFunctionDefCheck.h" +#include "clang/Sema/SemaDiagnostic.h" namespace clang { namespace tidy { @@ -73,6 +74,14 @@ // MSC CheckFactories.registerCheck("cert-msc30-c"); } + + void addWarningCheckAliases( + llvm::DenseMap &WarningCheckAliases) override { + WarningCheckAliases.try_emplace( + diag::warn_exception_caught_by_earlier_handler, "cert-err54-cpp"); + WarningCheckAliases.try_emplace( + diag::ext_offsetof_non_pod_type, "cert-exp59-cpp"); + } }; } // namespace cert Index: test/clang-tidy/cert-exp59-cpp.cpp =================================================================== --- /dev/null +++ test/clang-tidy/cert-exp59-cpp.cpp @@ -0,0 +1,16 @@ +// RUN: clang-tidy %s -- 2>&1 | FileCheck -implicit-check-not='{{warning:|error:}}' %s +// RUN: clang-tidy %s -checks='-*,cert-exp59-cpp' -- 2>&1 | FileCheck -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK2 %s +// RUN: clang-tidy %s -checks='-*,cert-exp59-cpp' -- -Wno-invalid-offsetof 2>&1 | FileCheck -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK2 %s + +#include + +struct D { + virtual void f() {} + int i; +}; + +void f() { + size_t Off = offsetof(D, i); + //CHECK: :[[@LINE-1]]:18: warning: offset of on non-POD type 'D' [clang-diagnostic-invalid-offsetof] + //CHECK2: :[[@LINE-2]]:18: warning: offset of on non-POD type 'D' [cert-exp59-cpp] +} Index: test/clang-tidy/warning-check-aliases.cpp =================================================================== --- /dev/null +++ test/clang-tidy/warning-check-aliases.cpp @@ -0,0 +1,21 @@ +// RUN: clang-tidy %s -- 2>&1 | FileCheck -implicit-check-not='{{warning:|error:}}' %s +// RUN: clang-tidy %s -checks='-*,cert-err54-cpp' -- 2>&1 | FileCheck -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK2 %s +// RUN: clang-tidy %s -checks='-*,cert-err54-cpp' -- -Wno-exceptions 2>&1 | FileCheck -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK2 %s + +class B {}; +class D : public B {}; + +void f() { + try { + + } catch (B &X) { + + } catch (D &Y) { + } +} + +//CHECK: :13:12: warning: exception of type 'D &' will be caught by earlier handler [clang-diagnostic-exceptions] +//CHECK: :11:12: note: for type 'B &' + +//CHECK2: :13:12: warning: exception of type 'D &' will be caught by earlier handler [cert-err54-cpp] +//CHECK2: :11:12: note: for type 'B &'