Index: include/clang/StaticAnalyzer/Core/CheckerManager.h =================================================================== --- include/clang/StaticAnalyzer/Core/CheckerManager.h +++ include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -141,7 +141,7 @@ using CheckerDtor = CheckerFn; //===----------------------------------------------------------------------===// -// registerChecker +// Checker registration. //===----------------------------------------------------------------------===// /// Used to register checkers. @@ -153,8 +153,7 @@ CHECKER *registerChecker(AT &&... Args) { CheckerTag tag = getTag(); CheckerRef &ref = CheckerTags[tag]; - if (ref) - return static_cast(ref); // already registered. + assert(!ref && "Checker already registered, use getChecker!"); CHECKER *checker = new CHECKER(std::forward(Args)...); checker->Name = CurrentCheckName; @@ -164,8 +163,17 @@ return checker; } + template + CHECKER *getChecker() { + CheckerTag tag = getTag(); + assert(CheckerTags.count(tag) != 0 && + "Requested checker is not registered! Maybe you should add it as a " + "dependency in Checkers.td?"); + return static_cast(CheckerTags[tag]); + } + //===----------------------------------------------------------------------===// -// Functions for running checkers for AST traversing.. +// Functions for running checkers for AST traversing. //===----------------------------------------------------------------------===// /// Run checkers handling Decls. Index: lib/StaticAnalyzer/Checkers/CStringChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -2485,7 +2485,7 @@ #define REGISTER_CHECKER(name) \ void ento::register##name(CheckerManager &mgr) { \ - CStringChecker *checker = mgr.registerChecker(); \ + CStringChecker *checker = mgr.getChecker(); \ checker->Filter.Check##name = true; \ checker->Filter.CheckName##name = mgr.getCurrentCheckName(); \ } \ Index: lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -609,8 +609,7 @@ } void ento::registerCallAndMessageUnInitRefArg(CheckerManager &mgr) { - CallAndMessageChecker *Checker = - mgr.registerChecker(); + CallAndMessageChecker *Checker = mgr.getChecker(); Checker->Check_CallAndMessageUnInitRefArg = true; Checker->CheckName_CallAndMessageUnInitRefArg = mgr.getCurrentCheckName(); } Index: lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -915,8 +915,7 @@ #define REGISTER_CHECKER(name) \ void ento::register##name(CheckerManager &mgr) { \ - SecuritySyntaxChecker *checker = \ - mgr.registerChecker(); \ + SecuritySyntaxChecker *checker = mgr.getChecker(); \ checker->filter.check_##name = true; \ checker->filter.checkName_##name = mgr.getCurrentCheckName(); \ } \ Index: lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp +++ lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp @@ -226,7 +226,7 @@ void ento::registerDirectIvarAssignmentForAnnotatedFunctions( CheckerManager &mgr) { - mgr.registerChecker()->ShouldSkipMethod = &AttrFilter; + mgr.getChecker()->ShouldSkipMethod = &AttrFilter; } bool ento::shouldRegisterDirectIvarAssignmentForAnnotatedFunctions( Index: lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -987,8 +987,7 @@ /// Register checkers. void ento::registerObjCGenericsChecker(CheckerManager &mgr) { - DynamicTypePropagation *checker = - mgr.registerChecker(); + DynamicTypePropagation *checker = mgr.getChecker(); checker->CheckGenerics = true; } Index: lib/StaticAnalyzer/Checkers/IteratorChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/IteratorChecker.cpp +++ lib/StaticAnalyzer/Checkers/IteratorChecker.cpp @@ -2404,7 +2404,7 @@ #define REGISTER_CHECKER(name) \ void ento::register##name(CheckerManager &Mgr) { \ - auto *checker = Mgr.registerChecker(); \ + auto *checker = Mgr.getChecker(); \ checker->ChecksEnabled[IteratorChecker::CK_##name] = true; \ checker->CheckNames[IteratorChecker::CK_##name] = \ Mgr.getCurrentCheckName(); \ Index: lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp +++ lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp @@ -746,7 +746,7 @@ #define REGISTER_CHECKER(name) \ void ento::register##name(CheckerManager &mgr) { \ IvarInvalidationChecker *checker = \ - mgr.registerChecker(); \ + mgr.getChecker(); \ checker->Filter.check_##name = true; \ checker->Filter.checkName_##name = mgr.getCurrentCheckName(); \ } \ Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -3089,16 +3089,16 @@ // Intended to be used in InnerPointerChecker to register the part of // MallocChecker connected to it. void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) { - MallocChecker *checker = mgr.registerChecker(); - checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( - "Optimistic", false, checker); - checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true; - checker->CheckNames[MallocChecker::CK_InnerPointerChecker] = - mgr.getCurrentCheckName(); + MallocChecker *checker = mgr.getChecker(); + checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true; + checker->CheckNames[MallocChecker::CK_InnerPointerChecker] = + mgr.getCurrentCheckName(); } void ento::registerDynamicMemoryModeling(CheckerManager &mgr) { - mgr.registerChecker(); + auto *checker = mgr.registerChecker(); + checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( + "Optimistic", false, checker); } bool ento::shouldRegisterDynamicMemoryModeling(const LangOptions &LO) { @@ -3107,9 +3107,7 @@ #define REGISTER_CHECKER(name) \ void ento::register##name(CheckerManager &mgr) { \ - MallocChecker *checker = mgr.registerChecker(); \ - checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( \ - "Optimistic", false, checker); \ + MallocChecker *checker = mgr.getChecker(); \ checker->ChecksEnabled[MallocChecker::CK_##name] = true; \ checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \ } \ Index: lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp +++ lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp @@ -317,8 +317,7 @@ void ento::registerNSErrorChecker(CheckerManager &mgr) { mgr.registerChecker(); - NSOrCFErrorDerefChecker *checker = - mgr.registerChecker(); + NSOrCFErrorDerefChecker *checker = mgr.getChecker(); checker->ShouldCheckNSError = true; } @@ -328,8 +327,7 @@ void ento::registerCFErrorChecker(CheckerManager &mgr) { mgr.registerChecker(); - NSOrCFErrorDerefChecker *checker = - mgr.registerChecker(); + NSOrCFErrorDerefChecker *checker = mgr.getChecker(); checker->ShouldCheckCFError = true; } Index: lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -1201,7 +1201,7 @@ #define REGISTER_CHECKER(name, trackingRequired) \ void ento::register##name##Checker(CheckerManager &mgr) { \ - NullabilityChecker *checker = mgr.registerChecker(); \ + NullabilityChecker *checker = mgr.getChecker(); \ checker->Filter.Check##name = true; \ checker->Filter.CheckName##name = mgr.getCurrentCheckName(); \ checker->NeedTracking = checker->NeedTracking || trackingRequired; \ Index: lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp +++ lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp @@ -1432,7 +1432,7 @@ } void ento::registerRetainCountChecker(CheckerManager &Mgr) { - auto *Chk = Mgr.registerChecker(); + auto *Chk = Mgr.getChecker(); Chk->TrackObjCAndCFObjects = true; } @@ -1452,7 +1452,7 @@ } void ento::registerOSObjectRetainCountChecker(CheckerManager &Mgr) { - auto *Chk = Mgr.registerChecker(); + auto *Chk = Mgr.getChecker(); if (!hasPrevCheckOSObjectOptionDisabled(Mgr.getAnalyzerOptions())) Chk->TrackOSObjects = true; } Index: lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp +++ lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp @@ -367,11 +367,11 @@ return true; } -#define REGISTER_CHECKER(name) \ - void ento::register##name(CheckerManager &Mgr) { \ - StackAddrEscapeChecker *Chk = \ - Mgr.registerChecker(); \ - Chk->ChecksEnabled[StackAddrEscapeChecker::CK_##name] = true; \ +#define REGISTER_CHECKER(name) \ + void ento::register##name(CheckerManager &Mgr) { \ + StackAddrEscapeChecker *Chk = \ + Mgr.getChecker(); \ + Chk->ChecksEnabled[StackAddrEscapeChecker::CK_##name] = true; \ } \ \ bool ento::shouldRegister##name(const LangOptions &LO) { \ Index: lib/StaticAnalyzer/Checkers/ValistChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ValistChecker.cpp +++ lib/StaticAnalyzer/Checkers/ValistChecker.cpp @@ -409,7 +409,7 @@ #define REGISTER_CHECKER(name) \ void ento::register##name##Checker(CheckerManager &mgr) { \ - ValistChecker *checker = mgr.registerChecker(); \ + ValistChecker *checker = mgr.getChecker(); \ checker->ChecksEnabled[ValistChecker::CK_##name] = true; \ checker->CheckNames[ValistChecker::CK_##name] = mgr.getCurrentCheckName(); \ } \ Index: test/Analysis/analyzer-checker-config.c =================================================================== --- test/Analysis/analyzer-checker-config.c +++ test/Analysis/analyzer-checker-config.c @@ -4,7 +4,7 @@ // RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config ..:Optimistic=true 2>&1 | FileCheck %s // RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.:Optimistic=true 2>&1 | FileCheck %s // RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unrelated:Optimistic=true 2>&1 | FileCheck %s -// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.Malloc:Optimistic=true +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.DynamicMemoryModeling:Optimistic=true // Just to test clang is working. # foo Index: test/Analysis/free.c =================================================================== --- test/Analysis/free.c +++ test/Analysis/free.c @@ -1,5 +1,11 @@ -// RUN: %clang_analyze_cc1 -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify %s -// RUN: %clang_analyze_cc1 -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify -analyzer-config unix.Malloc:Optimistic=true %s +// RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-store=region \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=unix.Malloc +// +// RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-store=region \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=unix.Malloc \ +// RUN: -analyzer-config unix.DynamicMemoryModeling:Optimistic=true typedef __typeof(sizeof(int)) size_t; void free(void *); void *alloca(size_t); Index: test/Analysis/outofbound.c =================================================================== --- test/Analysis/outofbound.c +++ test/Analysis/outofbound.c @@ -1,4 +1,8 @@ -// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,unix,alpha.security.ArrayBound -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s +// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-store=region -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=unix \ +// RUN: -analyzer-checker=alpha.security.ArrayBound \ +// RUN: -analyzer-config unix:Optimistic=true typedef __typeof(sizeof(int)) size_t; void *malloc(size_t); Index: test/Analysis/undef-buffers.c =================================================================== --- test/Analysis/undef-buffers.c +++ test/Analysis/undef-buffers.c @@ -1,4 +1,9 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,core.uninitialized -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s +// RUN: %clang_analyze_cc1 -analyzer-store=region -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=unix \ +// RUN: -analyzer-checker=core.uninitialized \ +// RUN: -analyzer-config unix:Optimistic=true + typedef __typeof(sizeof(int)) size_t; void *malloc(size_t); void free(void *);