Index: include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h =================================================================== --- include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h +++ include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h @@ -19,13 +19,17 @@ namespace clang { +class LangOptions; + namespace ento { + class CheckerManager; class CheckerRegistry; #define GET_CHECKERS #define CHECKER(FULLNAME, CLASS, HELPTEXT) \ - void register##CLASS(CheckerManager &mgr); + void register##CLASS(CheckerManager &mgr); \ + bool shouldRegister##CLASS(const LangOptions &LO); #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER #undef GET_CHECKERS Index: include/clang/StaticAnalyzer/Core/Checker.h =================================================================== --- include/clang/StaticAnalyzer/Core/Checker.h +++ include/clang/StaticAnalyzer/Core/Checker.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H #include "clang/Analysis/ProgramPoint.h" +#include "clang/Basic/LangOptions.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "llvm/Support/Casting.h" Index: include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h =================================================================== --- include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -70,6 +70,7 @@ class AnalyzerOptions; class DiagnosticsEngine; +class LangOptions; namespace ento { @@ -81,19 +82,23 @@ /// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker". class CheckerRegistry { public: - CheckerRegistry(ArrayRef plugins, DiagnosticsEngine &diags); + CheckerRegistry(ArrayRef plugins, DiagnosticsEngine &diags, + const LangOptions &LangOpts); /// Initialization functions perform any necessary setup for a checker. /// They should include a call to CheckerManager::registerChecker. using InitializationFunction = void (*)(CheckerManager &); + using ShouldRegisterFunction = bool (*)(const LangOptions &); struct CheckerInfo { InitializationFunction Initialize; + ShouldRegisterFunction ShouldRegister; StringRef FullName; StringRef Desc; - CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc) - : Initialize(fn), FullName(name), Desc(desc) {} + CheckerInfo(InitializationFunction rfn, ShouldRegisterFunction sfn, + StringRef name, StringRef desc) + : Initialize(rfn), ShouldRegister(sfn), FullName(name), Desc(desc) {} }; using CheckerInfoList = std::vector; @@ -105,11 +110,17 @@ mgr.registerChecker(); } + + template + static bool returnTrue(const LangOptions &LO) { + return true; + } + public: /// Adds a checker to the registry. Use this non-templated overload when your /// checker requires custom initialization. - void addChecker(InitializationFunction fn, StringRef fullName, - StringRef desc); + void addChecker(InitializationFunction rfn, ShouldRegisterFunction sfn, + StringRef fullName, StringRef desc); /// Adds a checker to the registry. Use this templated overload when your /// checker does not require any custom initialization. @@ -117,7 +128,8 @@ void addChecker(StringRef fullName, StringRef desc) { // Avoid MSVC's Compiler Error C2276: // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx - addChecker(&CheckerRegistry::initializeManager, fullName, desc); + addChecker(&CheckerRegistry::initializeManager, + &CheckerRegistry::returnTrue, fullName, desc); } /// Initializes a CheckerManager by calling the initialization functions for @@ -140,7 +152,9 @@ mutable CheckerInfoList Checkers; mutable llvm::StringMap Packages; + DiagnosticsEngine &Diags; + const LangOptions &LangOpts; }; } // namespace ento Index: include/clang/StaticAnalyzer/Frontend/FrontendActions.h =================================================================== --- include/clang/StaticAnalyzer/Frontend/FrontendActions.h +++ include/clang/StaticAnalyzer/Frontend/FrontendActions.h @@ -53,10 +53,11 @@ }; void printCheckerHelp(raw_ostream &OS, ArrayRef plugins, - DiagnosticsEngine &diags); + DiagnosticsEngine &diags, const LangOptions &LangOpts); void printEnabledCheckerList(raw_ostream &OS, ArrayRef plugins, const AnalyzerOptions &opts, - DiagnosticsEngine &diags); + DiagnosticsEngine &diags, + const LangOptions &LangOpts); void printAnalyzerConfigList(raw_ostream &OS); } // end GR namespace Index: lib/FrontendTool/ExecuteCompilerInvocation.cpp =================================================================== --- lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -240,7 +240,7 @@ // This should happen AFTER plugins have been loaded! if (Clang->getAnalyzerOpts()->ShowCheckerHelp) { ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins, - Clang->getDiagnostics()); + Clang->getDiagnostics(), Clang->getLangOpts()); return true; } @@ -249,7 +249,8 @@ ento::printEnabledCheckerList(llvm::outs(), Clang->getFrontendOpts().Plugins, *Clang->getAnalyzerOpts(), - Clang->getDiagnostics()); + Clang->getDiagnostics(), + Clang->getLangOpts()); } // Honor -analyzer-config-help. Index: lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -176,3 +176,7 @@ void ento::registerAnalysisOrderChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterAnalysisOrderChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp +++ lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp @@ -140,3 +140,7 @@ void ento::registerAnalyzerStatsChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterAnalyzerStatsChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp +++ lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp @@ -91,3 +91,7 @@ void ento::registerArrayBoundChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterArrayBoundChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp +++ lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp @@ -354,3 +354,7 @@ void ento::registerArrayBoundCheckerV2(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterArrayBoundCheckerV2(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp +++ lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp @@ -1243,27 +1243,54 @@ mgr.registerChecker(); } +bool ento::shouldRegisterNilArgChecker(const LangOptions &LO) { + return true; +} + void ento::registerCFNumberChecker(CheckerManager &mgr) { mgr.registerChecker(); } +bool ento::shouldRegisterCFNumberChecker(const LangOptions &LO) { + return true; +} + void ento::registerCFRetainReleaseChecker(CheckerManager &mgr) { mgr.registerChecker(); } +bool ento::shouldRegisterCFRetainReleaseChecker(const LangOptions &LO) { + return true; +} + void ento::registerClassReleaseChecker(CheckerManager &mgr) { mgr.registerChecker(); } +bool ento::shouldRegisterClassReleaseChecker(const LangOptions &LO) { + return true; +} + void ento::registerVariadicMethodTypeChecker(CheckerManager &mgr) { mgr.registerChecker(); } +bool ento::shouldRegisterVariadicMethodTypeChecker(const LangOptions &LO) { + return true; +} + void ento::registerObjCLoopChecker(CheckerManager &mgr) { mgr.registerChecker(); } -void -ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) { +bool ento::shouldRegisterObjCLoopChecker(const LangOptions &LO) { + return true; +} + +void ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterObjCNonNilReturnValueChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -183,3 +183,7 @@ void ento::registerBlockInCriticalSectionChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterBlockInCriticalSectionChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp +++ lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp @@ -155,3 +155,7 @@ void ento::registerBoolAssignmentChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterBoolAssignmentChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -119,3 +119,7 @@ void ento::registerBuiltinFunctionChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterBuiltinFunctionChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/CStringChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -2409,6 +2409,10 @@ CStringChecker *checker = mgr.registerChecker(); \ checker->Filter.Check##name = true; \ checker->Filter.CheckName##name = mgr.getCurrentCheckName(); \ + } \ + \ + bool ento::shouldRegister##name(const LangOptions &LO) { \ + return true; \ } REGISTER_CHECKER(CStringNullArg) Index: lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp +++ lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp @@ -290,3 +290,6 @@ mgr.registerChecker(); } +bool ento::shouldRegisterCStringSyntaxChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp +++ lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp @@ -60,3 +60,7 @@ void ento::registerCXXSelfAssignmentChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } + +bool ento::shouldRegisterCXXSelfAssignmentChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -614,6 +614,10 @@ mgr.registerChecker(); \ Checker->Filter.Check_##name = true; \ Checker->Filter.CheckName_##name = mgr.getCurrentCheckName(); \ + } \ + \ + bool ento::shouldRegister##name(const LangOptions &LO) { \ + return true; \ } REGISTER_CHECKER(CallAndMessageUnInitRefArg) Index: lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp +++ lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp @@ -140,10 +140,13 @@ } void ento::registerCastSizeChecker(CheckerManager &mgr) { + mgr.registerChecker(); +} + +bool ento::shouldRegisterCastSizeChecker(const LangOptions &LO) { // PR31226: C++ is more complicated than what this checker currently supports. // There are derived-to-base casts, there are different rules for 0-size // structures, no flexible arrays, etc. // FIXME: Disabled on C++ for now. - if (!mgr.getLangOpts().CPlusPlus) - mgr.registerChecker(); + return !LO.CPlusPlus; } Index: lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp +++ lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp @@ -120,3 +120,7 @@ void ento::registerCastToStructChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterCastToStructChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp +++ lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp @@ -1090,3 +1090,7 @@ Mgr.registerChecker(); } + +bool ento::shouldRegisterObjCDeallocChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp +++ lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp @@ -138,3 +138,7 @@ void ento::registerObjCMethSigsChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterObjCMethSigsChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -911,6 +911,10 @@ mgr.registerChecker(); \ checker->filter.check_##name = true; \ checker->filter.checkName_##name = mgr.getCurrentCheckName(); \ + } \ + \ + bool ento::shouldRegister##name(const LangOptions &LO) { \ + return true; \ } REGISTER_CHECKER(bcmp) Index: lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp +++ lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp @@ -91,3 +91,7 @@ void ento::registerSizeofPointerChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterSizeofPointerChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ChrootChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ChrootChecker.cpp +++ lib/StaticAnalyzer/Checkers/ChrootChecker.cpp @@ -153,3 +153,7 @@ void ento::registerChrootChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterChrootChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/CloneChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CloneChecker.cpp +++ lib/StaticAnalyzer/Checkers/CloneChecker.cpp @@ -202,3 +202,7 @@ void ento::registerCloneChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } + +bool ento::shouldRegisterCloneChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ConversionChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ConversionChecker.cpp +++ lib/StaticAnalyzer/Checkers/ConversionChecker.cpp @@ -196,3 +196,7 @@ void ento::registerConversionChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterConversionChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -479,3 +479,7 @@ void ento::registerDeadStoresChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterDeadStoresChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/DebugCheckers.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DebugCheckers.cpp +++ lib/StaticAnalyzer/Checkers/DebugCheckers.cpp @@ -48,6 +48,10 @@ mgr.registerChecker(); } +bool ento::shouldRegisterDominatorsTreeDumper(const LangOptions &LO) { + return true; +} + //===----------------------------------------------------------------------===// // LiveVariablesDumper //===----------------------------------------------------------------------===// @@ -68,6 +72,10 @@ mgr.registerChecker(); } +bool ento::shouldRegisterLiveVariablesDumper(const LangOptions &LO) { + return true; +} + //===----------------------------------------------------------------------===// // CFGViewer //===----------------------------------------------------------------------===// @@ -88,6 +96,10 @@ mgr.registerChecker(); } +bool ento::shouldRegisterCFGViewer(const LangOptions &LO) { + return true; +} + //===----------------------------------------------------------------------===// // CFGDumper //===----------------------------------------------------------------------===// @@ -114,6 +126,10 @@ mgr.registerChecker(); } +bool ento::shouldRegisterCFGDumper(const LangOptions &LO) { + return true; +} + //===----------------------------------------------------------------------===// // CallGraphViewer //===----------------------------------------------------------------------===// @@ -134,6 +150,10 @@ mgr.registerChecker(); } +bool ento::shouldRegisterCallGraphViewer(const LangOptions &LO) { + return true; +} + //===----------------------------------------------------------------------===// // CallGraphDumper //===----------------------------------------------------------------------===// @@ -154,6 +174,9 @@ mgr.registerChecker(); } +bool ento::shouldRegisterCallGraphDumper(const LangOptions &LO) { + return true; +} //===----------------------------------------------------------------------===// // ConfigDumper @@ -195,6 +218,10 @@ mgr.registerChecker(); } +bool ento::shouldRegisterConfigDumper(const LangOptions &LO) { + return true; +} + //===----------------------------------------------------------------------===// // ExplodedGraph Viewer //===----------------------------------------------------------------------===// @@ -214,3 +241,6 @@ mgr.registerChecker(); } +bool ento::shouldRegisterExplodedGraphViewer(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp +++ lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp @@ -148,3 +148,8 @@ void ento::registerDeleteWithNonVirtualDtorChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterDeleteWithNonVirtualDtorChecker( + const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -304,3 +304,7 @@ void ento::registerDereferenceChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterDereferenceChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp +++ lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp @@ -206,12 +206,6 @@ } } -// Register the checker that checks for direct accesses in all functions, -// except for the initialization and copy routines. -void ento::registerDirectIvarAssignment(CheckerManager &mgr) { - mgr.registerChecker(); -} - // Register the checker that checks for direct accesses in functions annotated // with __attribute__((annotate("objc_no_direct_instance_variable_assignment"))). static bool AttrFilter(const ObjCMethodDecl *M) { @@ -221,7 +215,22 @@ return true; } +// Register the checker that checks for direct accesses in all functions, +// except for the initialization and copy routines. +void ento::registerDirectIvarAssignment(CheckerManager &mgr) { + mgr.registerChecker(); +} + +bool ento::shouldRegisterDirectIvarAssignment(const LangOptions &LO) { + return true; +} + void ento::registerDirectIvarAssignmentForAnnotatedFunctions( CheckerManager &mgr) { mgr.registerChecker()->ShouldSkipMethod = &AttrFilter; } + +bool ento::shouldRegisterDirectIvarAssignmentForAnnotatedFunctions( + const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp +++ lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp @@ -99,3 +99,7 @@ void ento::registerDivZeroChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterDivZeroChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp +++ lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp @@ -206,3 +206,7 @@ void ento::registerDynamicTypeChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterDynamicTypeChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -993,6 +993,14 @@ checker->CheckGenerics = true; } +bool ento::shouldRegisterObjCGenericsChecker(const LangOptions &LO) { + return true; +} + void ento::registerDynamicTypePropagation(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterDynamicTypePropagation(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp +++ lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp @@ -126,3 +126,7 @@ void ento::registerEnumCastOutOfRangeChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterEnumCastOutOfRangeChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp +++ lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp @@ -398,3 +398,7 @@ void ento::registerExprInspectionChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } + +bool ento::shouldRegisterExprInspectionChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp +++ lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp @@ -65,3 +65,7 @@ void ento::registerFixedAddressChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterFixedAddressChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp +++ lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp @@ -222,8 +222,12 @@ emitDiagnostics(Match, "group", BR, ADC, this); } -} +} // end of anonymous namespace void ento::registerGCDAntipattern(CheckerManager &Mgr) { Mgr.registerChecker(); } + +bool ento::shouldRegisterGCDAntipattern(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/GTestChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/GTestChecker.cpp +++ lib/StaticAnalyzer/Checkers/GTestChecker.cpp @@ -289,11 +289,11 @@ } void ento::registerGTestChecker(CheckerManager &Mgr) { - const LangOptions &LangOpts = Mgr.getLangOpts(); + Mgr.registerChecker(); +} + +bool ento::shouldRegisterGTestChecker(const LangOptions &LO) { // gtest is a C++ API so there is no sense running the checker // if not compiling for C++. - if (!LangOpts.CPlusPlus) - return; - - Mgr.registerChecker(); + return LO.CPlusPlus; } Index: lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp +++ lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp @@ -746,3 +746,7 @@ void ento::registerGenericTaintChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterGenericTaintChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp +++ lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -513,3 +513,7 @@ void ento::registerIdenticalExprChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } + +bool ento::shouldRegisterIdenticalExprChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp +++ lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp @@ -310,3 +310,7 @@ registerInnerPointerCheckerAux(Mgr); Mgr.registerChecker(); } + +bool ento::shouldRegisterInnerPointerChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/IteratorChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/IteratorChecker.cpp +++ lib/StaticAnalyzer/Checkers/IteratorChecker.cpp @@ -2355,6 +2355,10 @@ checker->ChecksEnabled[IteratorChecker::CK_##name] = true; \ checker->CheckNames[IteratorChecker::CK_##name] = \ Mgr.getCurrentCheckName(); \ + } \ + \ + bool ento::shouldRegister##name(const LangOptions &LO) { \ + return true; \ } REGISTER_CHECKER(IteratorRangeChecker) Index: lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp +++ lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp @@ -742,6 +742,10 @@ mgr.registerChecker(); \ checker->Filter.check_##name = true; \ checker->Filter.checkName_##name = mgr.getCurrentCheckName(); \ + } \ + \ + bool ento::shouldRegister##name(const LangOptions &LO) { \ + return true; \ } REGISTER_CHECKER(InstanceVariableInvalidation) Index: lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp +++ lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp @@ -314,3 +314,7 @@ void ento::registerLLVMConventionsChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterLLVMConventionsChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp +++ lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp @@ -1402,10 +1402,22 @@ false, checker); } +bool ento::shouldRegisterNonLocalizedStringChecker(const LangOptions &LO) { + return true; +} + void ento::registerEmptyLocalizationContextChecker(CheckerManager &mgr) { mgr.registerChecker(); } +bool ento::shouldRegisterEmptyLocalizationContextChecker(const LangOptions &LO) { + return true; +} + void ento::registerPluralMisuseChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterPluralMisuseChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp +++ lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp @@ -188,3 +188,7 @@ void clang::ento::registerMPIChecker(CheckerManager &MGR) { MGR.registerChecker(); } + +bool clang::ento::shouldRegisterMPIChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp +++ lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp @@ -662,3 +662,7 @@ void ento::registerMacOSKeychainAPIChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterMacOSKeychainAPIChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp +++ lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp @@ -174,3 +174,7 @@ void ento::registerMacOSXAPIChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterMacOSXAPIChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -3106,6 +3106,10 @@ } } +bool ento::shouldRegisterNewDeleteLeaksChecker(const LangOptions &LO) { + return true; +} + // Intended to be used in InnerPointerChecker to register the part of // MallocChecker connected to it. void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) { @@ -3126,6 +3130,10 @@ "Optimistic", false, checker); \ checker->ChecksEnabled[MallocChecker::CK_##name] = true; \ checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \ + } \ + \ + bool ento::shouldRegister##name(const LangOptions &LO) { \ + return true; \ } REGISTER_CHECKER(MallocChecker) Index: lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp @@ -331,7 +331,10 @@ OutputPossibleOverflows(PossibleMallocOverflows, D, BR, mgr); } -void -ento::registerMallocOverflowSecurityChecker(CheckerManager &mgr) { +void ento::registerMallocOverflowSecurityChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterMallocOverflowSecurityChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp @@ -250,3 +250,7 @@ void ento::registerMallocSizeofChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterMallocSizeofChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp +++ lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp @@ -514,6 +514,11 @@ } } } + void ento::registerMisusedMovedObjectChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterMisusedMovedObjectChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp +++ lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp @@ -88,3 +88,7 @@ mgr.getAnalyzerOptions() .getCheckerIntegerOption("MmapProtRead", 0x01, Mwec); } + +bool ento::shouldRegisterMmapWriteExecChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp +++ lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp @@ -76,6 +76,9 @@ } void ento::registerNSAutoreleasePoolChecker(CheckerManager &mgr) { - if (mgr.getLangOpts().getGC() != LangOptions::NonGC) - mgr.registerChecker(); + mgr.registerChecker(); +} + +bool ento::shouldRegisterNSAutoreleasePoolChecker(const LangOptions &LO) { + return LO.getGC() != LangOptions::NonGC; } Index: lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp +++ lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp @@ -315,9 +315,17 @@ checker->ShouldCheckNSError = true; } +bool ento::shouldRegisterNSErrorChecker(const LangOptions &LO) { + return true; +} + void ento::registerCFErrorChecker(CheckerManager &mgr) { mgr.registerChecker(); NSOrCFErrorDerefChecker *checker = mgr.registerChecker(); checker->ShouldCheckCFError = true; } + +bool ento::shouldRegisterCFErrorChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp +++ lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp @@ -143,3 +143,7 @@ void ento::registerNoReturnFunctionChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterNoReturnFunctionChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -217,3 +217,7 @@ void ento::registerNonNullParamChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterNonNullParamChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp +++ lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp @@ -138,3 +138,7 @@ void ento::registerNonnullGlobalConstantsChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } + +bool ento::shouldRegisterNonnullGlobalConstantsChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -1190,8 +1190,12 @@ checker->NeedTracking = checker->NeedTracking || trackingRequired; \ checker->NoDiagnoseCallsToSystemHeaders = \ checker->NoDiagnoseCallsToSystemHeaders || \ - mgr.getAnalyzerOptions().getCheckerBooleanOption( \ + mgr.getAnalyzerOptions().getCheckerBooleanOption( \ "NoDiagnoseCallsToSystemHeaders", false, checker, true); \ + } \ + \ + bool ento::shouldRegister##name##Checker(const LangOptions &LO) { \ + return true; \ } // The checks are likely to be turned on by default and it is possible to do Index: lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp +++ lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp @@ -348,3 +348,7 @@ Chk->Pedantic = Mgr.getAnalyzerOptions().getCheckerBooleanOption("Pedantic", false, Chk); } + +bool ento::shouldRegisterNumberObjectConversionChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp +++ lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp @@ -89,6 +89,9 @@ } void ento::registerObjCAtSyncChecker(CheckerManager &mgr) { - if (mgr.getLangOpts().ObjC) - mgr.registerChecker(); + mgr.registerChecker(); +} + +bool ento::shouldRegisterObjCAtSyncChecker(const LangOptions &LO) { + return LO.ObjC; } Index: lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp +++ lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp @@ -207,3 +207,7 @@ void ento::registerAutoreleaseWriteChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } + +bool ento::shouldRegisterAutoreleaseWriteChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp +++ lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp @@ -172,3 +172,7 @@ void ento::registerObjCContainersASTChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterObjCContainersASTChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp +++ lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp @@ -170,3 +170,7 @@ void ento::registerObjCContainersChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterObjCContainersChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp +++ lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp @@ -222,6 +222,9 @@ Mgr.registerChecker(); } +bool ento::shouldRegisterObjCSuperCallChecker(const LangOptions &LO) { + return true; +} /* ToDo list for expanding this check in the future, the list is not exhaustive. Index: lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp +++ lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp @@ -79,3 +79,7 @@ void ento::registerObjCPropertyChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } + +bool ento::shouldRegisterObjCPropertyChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp +++ lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp @@ -437,3 +437,7 @@ void ento::registerObjCSelfInitChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterObjCSelfInitChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp +++ lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp @@ -282,8 +282,9 @@ //===----------------------------------------------------------------------===// void ento::registerObjCSuperDeallocChecker(CheckerManager &Mgr) { - const LangOptions &LangOpts = Mgr.getLangOpts(); - if (LangOpts.getGC() == LangOptions::GCOnly || LangOpts.ObjCAutoRefCount) - return; Mgr.registerChecker(); } + +bool ento::shouldRegisterObjCSuperDeallocChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp +++ lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp @@ -186,3 +186,7 @@ void ento::registerObjCUnusedIvarsChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterObjCUnusedIvarsChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/PaddingChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/PaddingChecker.cpp +++ lib/StaticAnalyzer/Checkers/PaddingChecker.cpp @@ -351,3 +351,7 @@ void ento::registerPaddingChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } + +bool ento::shouldRegisterPaddingChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp +++ lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp @@ -343,3 +343,7 @@ void ento::registerPointerArithChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterPointerArithChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp +++ lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp @@ -73,3 +73,7 @@ void ento::registerPointerSubChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterPointerSubChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp +++ lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp @@ -481,3 +481,7 @@ void ento::registerPthreadLockChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterPthreadLockChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp +++ lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp @@ -1513,3 +1513,7 @@ Chk->ShouldCheckOSObjectRetainCount = Options.getCheckerBooleanOption( "CheckOSObject", true, Chk); } + +bool ento::shouldRegisterRetainCountChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp +++ lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp @@ -90,3 +90,7 @@ void ento::registerReturnPointerRangeChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterReturnPointerRangeChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp +++ lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp @@ -121,3 +121,7 @@ void ento::registerReturnUndefChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterReturnUndefChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp +++ lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp @@ -221,3 +221,7 @@ void ento::registerRunLoopAutoreleaseLeakChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterRunLoopAutoreleaseLeakChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp +++ lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp @@ -269,3 +269,8 @@ void ento::registerSimpleStreamChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +// This checker should be enabled regardless of how language options are set. +bool ento::shouldRegisterSimpleStreamChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp +++ lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp @@ -365,6 +365,10 @@ StackAddrEscapeChecker *Chk = \ Mgr.registerChecker(); \ Chk->ChecksEnabled[StackAddrEscapeChecker::CK_##name] = true; \ + } \ + \ + bool ento::shouldRegister##name(const LangOptions &LO) { \ + return true; \ } REGISTER_CHECKER(StackAddrEscapeChecker) Index: lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -1056,3 +1056,7 @@ // class, turning on different function summaries. mgr.registerChecker(); } + +bool ento::shouldRegisterStdCLibraryFunctionsChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/StreamChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -409,3 +409,7 @@ void ento::registerStreamChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterStreamChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp +++ lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp @@ -60,3 +60,7 @@ void ento::registerTaintTesterChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterTaintTesterChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp +++ lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp @@ -261,3 +261,7 @@ void ento::registerTestAfterDivZeroChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterTestAfterDivZeroChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/TraversalChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/TraversalChecker.cpp +++ lib/StaticAnalyzer/Checkers/TraversalChecker.cpp @@ -65,6 +65,10 @@ mgr.registerChecker(); } +bool ento::shouldRegisterTraversalDumper(const LangOptions &LO) { + return true; +} + //------------------------------------------------------------------------------ namespace { @@ -112,3 +116,7 @@ void ento::registerCallDumper(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterCallDumper(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp +++ lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp @@ -249,7 +249,10 @@ } // end empty namespace - void ento::registerTrustNonnullChecker(CheckerManager &Mgr) { Mgr.registerChecker(Mgr.getASTContext()); } + +bool ento::shouldRegisterTrustNonnullChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp +++ lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp @@ -109,3 +109,7 @@ void ento::registerUndefBranchChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterUndefBranchChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp +++ lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp @@ -100,3 +100,7 @@ void ento::registerUndefCapturedBlockVarChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterUndefCapturedBlockVarChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp @@ -186,3 +186,7 @@ void ento::registerUndefResultChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterUndefResultChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp +++ lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp @@ -62,3 +62,7 @@ void ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterUndefinedArraySubscriptChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp +++ lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp @@ -120,3 +120,7 @@ void ento::registerUndefinedAssignmentChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterUndefinedAssignmentChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -536,3 +536,7 @@ AnOpts.getCheckerStringOption("IgnoreRecordsWithField", /*DefaultVal*/ "", Chk); } + +bool ento::shouldRegisterUninitializedObjectChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp +++ lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp @@ -473,7 +473,11 @@ #define REGISTER_CHECKER(Name) \ void ento::registerUnixAPI##Name##Checker(CheckerManager &mgr) { \ mgr.registerChecker()->Check##Name = true; \ - } + } \ + \ + bool ento::shouldRegisterUnixAPI##Name##Checker(const LangOptions &LO) { \ + return true; \ + } REGISTER_CHECKER(Misuse) REGISTER_CHECKER(Portability) Index: lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp +++ lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp @@ -257,3 +257,7 @@ void ento::registerUnreachableCodeChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterUnreachableCodeChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp +++ lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp @@ -183,3 +183,7 @@ void ento::registerVLASizeChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterVLASizeChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/ValistChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ValistChecker.cpp +++ lib/StaticAnalyzer/Checkers/ValistChecker.cpp @@ -405,6 +405,10 @@ ValistChecker *checker = mgr.registerChecker(); \ checker->ChecksEnabled[ValistChecker::CK_##name] = true; \ checker->CheckNames[ValistChecker::CK_##name] = mgr.getCurrentCheckName(); \ + } \ + \ + bool ento::shouldRegister##name##Checker(const LangOptions &LO) { \ + return true; \ } REGISTER_CHECKER(Uninitialized) Index: lib/StaticAnalyzer/Checkers/VforkChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/VforkChecker.cpp +++ lib/StaticAnalyzer/Checkers/VforkChecker.cpp @@ -216,3 +216,7 @@ void ento::registerVforkChecker(CheckerManager &mgr) { mgr.registerChecker(); } + +bool ento::shouldRegisterVforkChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp +++ lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp @@ -283,3 +283,7 @@ mgr.getAnalyzerOptions().getCheckerBooleanOption("PureOnly", false, checker); } + +bool ento::shouldRegisterVirtualCallChecker(const LangOptions &LO) { + return true; +} Index: lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp =================================================================== --- lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -34,7 +34,7 @@ DiagnosticsEngine &diags) { auto checkerMgr = llvm::make_unique(context, opts); - CheckerRegistry allCheckers(plugins, diags); + CheckerRegistry allCheckers(plugins, diags, context.getLangOpts()); for (const auto &Fn : checkerRegistrationFns) Fn(allCheckers); @@ -47,20 +47,22 @@ } void ento::printCheckerHelp(raw_ostream &out, ArrayRef plugins, - DiagnosticsEngine &diags) { + DiagnosticsEngine &diags, + const LangOptions &langOpts) { out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n"; out << "USAGE: -analyzer-checker \n\n"; - CheckerRegistry(plugins, diags).printHelp(out); + CheckerRegistry(plugins, diags, langOpts).printHelp(out); } void ento::printEnabledCheckerList(raw_ostream &out, ArrayRef plugins, const AnalyzerOptions &opts, - DiagnosticsEngine &diags) { + DiagnosticsEngine &diags, + const LangOptions &langOpts) { out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n"; - CheckerRegistry(plugins, diags).printList(out, opts); + CheckerRegistry(plugins, diags, langOpts).printList(out, opts); } void ento::printAnalyzerConfigList(raw_ostream &out) { Index: lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp =================================================================== --- lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp +++ lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -39,10 +39,13 @@ } CheckerRegistry::CheckerRegistry(ArrayRef plugins, - DiagnosticsEngine &diags) : Diags(diags) { + DiagnosticsEngine &diags, + const LangOptions &LangOpts) + : Diags(diags), LangOpts(LangOpts) { + #define GET_CHECKERS #define CHECKER(FULLNAME, CLASS, HELPTEXT) \ - addChecker(register##CLASS, FULLNAME, HELPTEXT); + addChecker(register##CLASS, shouldRegister##CLASS, FULLNAME, HELPTEXT); #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER #undef GET_CHECKERS @@ -114,7 +117,7 @@ for (const std::pair &opt : Opts.CheckersControlList) { // Use a binary search to find the possible start of the package. - CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.first, ""); + CheckerRegistry::CheckerInfo packageInfo(nullptr, nullptr, opt.first, ""); auto firstRelatedChecker = std::lower_bound(Checkers.cbegin(), end, packageInfo, checkerNameLT); @@ -137,22 +140,25 @@ // Step through all the checkers in the package. for (auto lastRelatedChecker = firstRelatedChecker+size; firstRelatedChecker != lastRelatedChecker; ++firstRelatedChecker) - if (opt.second) - enabledCheckers.insert(&*firstRelatedChecker); - else + if (opt.second) { + if (firstRelatedChecker->ShouldRegister(LangOpts)) + enabledCheckers.insert(&*firstRelatedChecker); + } else { enabledCheckers.remove(&*firstRelatedChecker); + } } return enabledCheckers; } -void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name, - StringRef desc) { - Checkers.push_back(CheckerInfo(fn, name, desc)); +void CheckerRegistry::addChecker(InitializationFunction rfn, + ShouldRegisterFunction sfn, + StringRef fullName, StringRef desc) { + Checkers.push_back(CheckerInfo(rfn, sfn, fullName, desc)); // Record the presence of the checker in its packages. StringRef packageName, leafName; - std::tie(packageName, leafName) = name.rsplit(PackageSeparator); + std::tie(packageName, leafName) = fullName.rsplit(PackageSeparator); while (!leafName.empty()) { Packages[packageName] += 1; std::tie(packageName, leafName) = packageName.rsplit(PackageSeparator);