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,13 @@ CheckNames.push_back(CheckFactory.first); } + for (const auto &Alias : Context.WarningCheckAliases) + if (Context.isCheckEnabled(Alias.second)) + CheckNames.push_back(Alias.second); + + for (const auto &Diag : Context.getEnabledClangDiagnostics()) + CheckNames.push_back("clang-diagnostic-" + Diag); + for (const auto &AnalyzerCheck : getCheckersControlList(Context)) CheckNames.push_back(AnalyzerCheckNamePrefix + AnalyzerCheck.first); @@ -492,6 +500,15 @@ if (Opts.ExtraArgs) AdjustedArgs.insert(AdjustedArgs.end(), Opts.ExtraArgs->begin(), Opts.ExtraArgs->end()); + + AdjustedArgs.push_back("-Wno-everything"); + for (const auto &Diag : Context.getEnabledClangDiagnostics()) + AdjustedArgs.push_back("-W" + Diag); + + for (const auto &Alias : Context.WarningCheckAliases) + if (Context.isCheckEnabled(Alias.second)) + AdjustedArgs.push_back("-W" + 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,10 @@ return CurrentBuildDirectory; } + std::vector getEnabledClangDiagnostics(); + + llvm::DenseMap WarningCheckAliases; + private: // Calls setDiagnosticsEngine() and storeError(). friend class ClangTidyDiagnosticConsumer; Index: clang-tidy/ClangTidyDiagnosticConsumer.cpp =================================================================== --- clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -23,6 +23,7 @@ #include "clang/Frontend/DiagnosticRenderer.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" +#include #include #include using namespace clang; @@ -258,6 +259,22 @@ return ""; } +std::vector ClangTidyContext::getEnabledClangDiagnostics() { + std::vector Diags; + DiagnosticIDs::getAllDiagnostics(diag::Flavor::WarningOrError, Diags); + std::vector EnabledClangDiagnostics; + for (unsigned DiagID : Diags) { + auto Flag = DiagnosticIDs::getWarningOptionForDiag(DiagID).str(); + if (!Flag.empty() && isCheckEnabled("clang-diagnostic-" + Flag)) + EnabledClangDiagnostics.push_back(Flag); + } + std::sort(EnabledClangDiagnostics.begin(), EnabledClangDiagnostics.end()); + EnabledClangDiagnostics.erase(std::unique(EnabledClangDiagnostics.begin(), + EnabledClangDiagnostics.end()), + EnabledClangDiagnostics.end()); + return EnabledClangDiagnostics; +} + ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer( ClangTidyContext &Ctx, bool RemoveIncompatibleErrors) : Context(Ctx), RemoveIncompatibleErrors(RemoveIncompatibleErrors), @@ -407,9 +424,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(WarningOption); + 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 @@ -73,6 +73,12 @@ // MSC CheckFactories.registerCheck("cert-msc30-c"); } + + void addWarningCheckAliases(llvm::DenseMap + &WarningCheckAliases) override { + WarningCheckAliases.try_emplace("exceptions", "cert-err54-cpp"); + WarningCheckAliases.try_emplace("invalid-offsetof", "cert-exp59-cpp"); + } }; } // namespace cert Index: clang-tidy/tool/ClangTidyMain.cpp =================================================================== --- clang-tidy/tool/ClangTidyMain.cpp +++ clang-tidy/tool/ClangTidyMain.cpp @@ -52,7 +52,6 @@ )"); const char DefaultChecks[] = // Enable these checks by default: - "clang-diagnostic-*," // * compiler diagnostics "clang-analyzer-*"; // * Static Analyzer checks static cl::opt Checks("checks", cl::desc(R"( 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 -checks='-*,clang-diagnostic-invalid-offsetof' -- 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 -- 2>&1 | FileCheck -allow-empty -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK3 %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-standard-layout type 'D' [clang-diagnostic-invalid-offsetof] + //CHECK2: :[[@LINE-2]]:18: warning: offset of on non-standard-layout type 'D' [cert-exp59-cpp] +} Index: test/clang-tidy/custom-diagnostics.cpp =================================================================== --- test/clang-tidy/custom-diagnostics.cpp +++ test/clang-tidy/custom-diagnostics.cpp @@ -1,4 +1,9 @@ -// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-shadow,clang-diagnostic-float-conversion' %s -- | count 0 +// RUN: clang-tidy -checks='-*,modernize-use-override' %s -- | count 0 +// +// Clang-diagnostic checks completely override extra args: +// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-shadow,clang-diagnostic-float-conversion' \ +// RUN: -config='{ExtraArgs: ["-Wno-shadow","-Wno-float-conversion","-Wunused-variable"], ExtraArgsBefore: ["-Wno-shadow","-Wno-float-conversion","-Wunused-variable"]}' %s -- \ +// RUN: | FileCheck -implicit-check-not='{{warning:|error:}}' %s // // Enable warnings using -config: // RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-shadow,clang-diagnostic-float-conversion' \ Index: test/clang-tidy/diagnostic.cpp =================================================================== --- test/clang-tidy/diagnostic.cpp +++ test/clang-tidy/diagnostic.cpp @@ -1,13 +1,11 @@ // RUN: clang-tidy -checks='-*,modernize-use-override' %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s -// RUN: clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s -// RUN: clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s -// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s +// RUN: clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s +// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s // // Now repeat the tests and ensure no other errors appear on stderr: // RUN: clang-tidy -checks='-*,modernize-use-override' %s.nonexistent.cpp -- 2>&1 | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s -// RUN: clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %s -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s -// RUN: clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s -// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE 2>&1 | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s +// RUN: clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s +// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE 2>&1 | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s // // Now create a directory with a compilation database file and ensure we don't // use it after failing to parse commands from the command line: @@ -16,25 +14,21 @@ // RUN: echo '[{"directory": "%/T/diagnostics/","command": "clang++ -fan-option-from-compilation-database -c %/T/diagnostics/input.cpp", "file": "%/T/diagnostics/input.cpp"}]' > %T/diagnostics/compile_commands.json // RUN: cat %s > %T/diagnostics/input.cpp // RUN: clang-tidy -checks='-*,modernize-use-override' %T/diagnostics/nonexistent.cpp -- 2>&1 | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s -// RUN: clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %T/diagnostics/input.cpp -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s -// RUN: clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %T/diagnostics/input.cpp -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s -// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %T/diagnostics/input.cpp -- -DMACRO_FROM_COMMAND_LINE 2>&1 | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s -// RUN: clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %T/diagnostics/input.cpp 2>&1 | FileCheck -check-prefix=CHECK5 -implicit-check-not='{{warning:|error:}}' %s +// RUN: clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %T/diagnostics/input.cpp -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s +// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %T/diagnostics/input.cpp -- -DMACRO_FROM_COMMAND_LINE 2>&1 | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s +// RUN: clang-tidy -checks='-*,clang-diagnostic-literal-conversion,google-explicit-constructor' %T/diagnostics/input.cpp 2>&1 | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s // CHECK1: error: error reading '{{.*}}nonexistent.cpp' [clang-diagnostic-error] // CHECK2: error: unknown argument: '-fan-unknown-option' [clang-diagnostic-error] -// CHECK3: error: unknown argument: '-fan-unknown-option' [clang-diagnostic-error] -// CHECK5: error: unknown argument: '-fan-option-from-compilation-database' [clang-diagnostic-error] +// CHECK4: error: unknown argument: '-fan-option-from-compilation-database' [clang-diagnostic-error] -// CHECK2: :[[@LINE+3]]:9: warning: implicit conversion from 'double' to 'int' changes value from 1.5 to 1 [clang-diagnostic-literal-conversion] -// CHECK3: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to 'int' changes value -// CHECK5: :[[@LINE+1]]:9: warning: implicit conversion from 'double' to 'int' changes value +// CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to 'int' changes value from 1.5 to 1 [clang-diagnostic-literal-conversion] +// CHECK4: :[[@LINE+1]]:9: warning: implicit conversion from 'double' to 'int' changes value int a = 1.5; -// CHECK2: :[[@LINE+3]]:11: warning: single-argument constructors must be marked explicit -// CHECK3: :[[@LINE+2]]:11: warning: single-argument constructors must be marked explicit -// CHECK5: :[[@LINE+1]]:11: warning: single-argument constructors must be marked explicit +// CHECK2: :[[@LINE+2]]:11: warning: single-argument constructors must be marked explicit +// CHECK4: :[[@LINE+1]]:11: warning: single-argument constructors must be marked explicit class A { A(int) {} }; #define MACRO_FROM_COMMAND_LINE -// CHECK4: :[[@LINE-1]]:9: warning: 'MACRO_FROM_COMMAND_LINE' macro redefined +// CHECK3: :[[@LINE-1]]:9: warning: 'MACRO_FROM_COMMAND_LINE' macro redefined Index: test/clang-tidy/list-clang-diagnostics.cpp =================================================================== --- /dev/null +++ test/clang-tidy/list-clang-diagnostics.cpp @@ -0,0 +1,7 @@ +// RUN: clang-tidy -checks='-*,clang-diagnostic-*' -list-checks 2>&1 | FileCheck -match-full-lines %s +// Check that some basic diagnostics are listed as well as some that have aliases. + +// CHECK: clang-diagnostic-conversion +// CHECK: clang-diagnostic-division-by-zero +// CHECK: clang-diagnostic-exceptions +// CHECK: clang-diagnostic-invalid-offsetof Index: test/clang-tidy/misc-suspicious-semicolon-fail.cpp =================================================================== --- test/clang-tidy/misc-suspicious-semicolon-fail.cpp +++ test/clang-tidy/misc-suspicious-semicolon-fail.cpp @@ -1,8 +1,8 @@ // RUN: clang-tidy %s -checks="-*,misc-suspicious-semicolon" -- -DERROR 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-ERROR \ // RUN: -implicit-check-not="{{warning|error}}:" -// RUN: clang-tidy %s -checks="-*,misc-suspicious-semicolon,clang-diagnostic*" \ -// RUN: -- -DWERROR -Wno-everything -Werror=unused-variable 2>&1 \ +// RUN: not clang-tidy %s -checks="-*,misc-suspicious-semicolon,clang-diagnostic-unused-variable" \ +// RUN: -warnings-as-errors=clang-diagnostic-unused-variable -- -DWERROR 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-WERROR \ // RUN: -implicit-check-not="{{warning|error}}:" @@ -19,7 +19,7 @@ // CHECK-ERROR: :[[@LINE-1]]:8: error: expected ';' at end of declaration [clang-diagnostic-error] #elif WERROR int a; - // CHECK-WERROR: :[[@LINE-1]]:7: error: unused variable 'a' [clang-diagnostic-unused-variable] + // CHECK-WERROR: :[[@LINE-1]]:7: error: unused variable 'a' [clang-diagnostic-unused-variable,-warnings-as-errors] #else #error "One of ERROR or WERROR should be defined. #endif Index: test/clang-tidy/validate-check-names.cpp =================================================================== --- test/clang-tidy/validate-check-names.cpp +++ test/clang-tidy/validate-check-names.cpp @@ -1,2 +1,2 @@ // Check names may only contain alphanumeric characters, '-', '_', and '.'. -// RUN: clang-tidy -checks=* -list-checks | grep '^ ' | cut -b5- | not grep -v '^[a-zA-Z0-9_.\-]\+$' +// RUN: clang-tidy -checks=*,-clang-diagnostic* -list-checks | grep '^ ' | cut -b5- | not grep -v '^[a-zA-Z0-9_.\-]\+$' Index: test/clang-tidy/warning-check-aliases.cpp =================================================================== --- /dev/null +++ test/clang-tidy/warning-check-aliases.cpp @@ -0,0 +1,19 @@ +// RUN: clang-tidy %s -checks='-*,clang-diagnostic-exceptions' -- 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 -- 2>&1 | FileCheck -allow-empty -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK3 %s + +class B {}; +class D : public B {}; + +void f() { + try { + } catch (B &X) { + } catch (D &Y) { + } +} + +//CHECK: :11:12: warning: exception of type 'D &' will be caught by earlier handler [clang-diagnostic-exceptions] +//CHECK: :10:12: note: for type 'B &' + +//CHECK2: :11:12: warning: exception of type 'D &' will be caught by earlier handler [cert-err54-cpp] +//CHECK2: :10:12: note: for type 'B &' Index: test/clang-tidy/werrors-diagnostics.cpp =================================================================== --- test/clang-tidy/werrors-diagnostics.cpp +++ test/clang-tidy/werrors-diagnostics.cpp @@ -1,11 +1,10 @@ -// RUN: clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic*' \ -// RUN: -- -Wunused-variable 2>&1 \ +// RUN: clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic-unused-variable' -- 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-WARN -implicit-check-not='{{warning|error}}:' -// RUN: not clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic*' \ -// RUN: -warnings-as-errors='clang-diagnostic*' -- -Wunused-variable 2>&1 \ +// RUN: not clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic-unused-variable' \ +// RUN: -warnings-as-errors='clang-diagnostic*' -- 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-WERR -implicit-check-not='{{warning|error}}:' -// RUN: not clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic*' \ -// RUN: -warnings-as-errors='clang-diagnostic*' -quiet -- -Wunused-variable 2>&1 \ +// RUN: not clang-tidy %s -checks='-*,llvm-namespace-comment,clang-diagnostic-unused-variable' \ +// RUN: -warnings-as-errors='clang-diagnostic*' -quiet -- 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-WERR-QUIET -implicit-check-not='{{warning|error}}:' void f() { int i; }