forked from OSchip/llvm-project
[analyzer] Supply all checkers with a shouldRegister function
Introduce the boolean ento::shouldRegister##CHECKERNAME(const LangOptions &LO) function very similarly to ento::register##CHECKERNAME. This will force every checker to implement this function, but maybe it isn't that bad: I saw a lot of ObjC or C++ specific checkers that should probably not register themselves based on some LangOptions (mine too), but they do anyways. A big benefit of this is that all registry functions now register their checker, once it is called, registration is guaranteed. This patch is a part of a greater effort to reinvent checker registration, more info here: D54438#1315953 Differential Revision: https://reviews.llvm.org/D55424 llvm-svn: 352277
This commit is contained in:
parent
db07683d86
commit
058a7a450a
|
@ -18,13 +18,17 @@
|
|||
|
||||
namespace clang {
|
||||
|
||||
class LangOptions;
|
||||
|
||||
namespace ento {
|
||||
|
||||
class CheckerManager;
|
||||
class CheckerRegistry;
|
||||
|
||||
#define GET_CHECKERS
|
||||
#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \
|
||||
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
|
||||
|
|
|
@ -14,6 +14,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"
|
||||
|
|
|
@ -69,6 +69,7 @@ namespace clang {
|
|||
|
||||
class AnalyzerOptions;
|
||||
class DiagnosticsEngine;
|
||||
class LangOptions;
|
||||
|
||||
namespace ento {
|
||||
|
||||
|
@ -80,21 +81,24 @@ namespace ento {
|
|||
/// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
|
||||
class CheckerRegistry {
|
||||
public:
|
||||
CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags);
|
||||
CheckerRegistry(ArrayRef<std::string> 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;
|
||||
StringRef DocumentationUri;
|
||||
|
||||
CheckerInfo(InitializationFunction Fn, StringRef Name, StringRef Desc,
|
||||
StringRef DocsUri)
|
||||
: Initialize(Fn), FullName(Name), Desc(Desc),
|
||||
CheckerInfo(InitializationFunction Fn, ShouldRegisterFunction sfn,
|
||||
StringRef Name, StringRef Desc, StringRef DocsUri)
|
||||
: Initialize(Fn), ShouldRegister(sfn), FullName(Name), Desc(Desc),
|
||||
DocumentationUri(DocsUri) {}
|
||||
};
|
||||
|
||||
|
@ -107,11 +111,17 @@ private:
|
|||
mgr.registerChecker<T>();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
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,
|
||||
StringRef DocsUri);
|
||||
void addChecker(InitializationFunction Fn, ShouldRegisterFunction sfn,
|
||||
StringRef FullName, StringRef Desc, StringRef DocsUri);
|
||||
|
||||
/// Adds a checker to the registry. Use this templated overload when your
|
||||
/// checker does not require any custom initialization.
|
||||
|
@ -119,7 +129,8 @@ public:
|
|||
void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri) {
|
||||
// Avoid MSVC's Compiler Error C2276:
|
||||
// http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
|
||||
addChecker(&CheckerRegistry::initializeManager<T>, FullName, Desc, DocsUri);
|
||||
addChecker(&CheckerRegistry::initializeManager<T>,
|
||||
&CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri);
|
||||
}
|
||||
|
||||
/// Initializes a CheckerManager by calling the initialization functions for
|
||||
|
@ -142,7 +153,9 @@ private:
|
|||
|
||||
mutable CheckerInfoList Checkers;
|
||||
mutable llvm::StringMap<size_t> Packages;
|
||||
|
||||
DiagnosticsEngine &Diags;
|
||||
const LangOptions &LangOpts;
|
||||
};
|
||||
|
||||
} // namespace ento
|
||||
|
|
|
@ -52,10 +52,11 @@ private:
|
|||
};
|
||||
|
||||
void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins,
|
||||
DiagnosticsEngine &diags);
|
||||
DiagnosticsEngine &diags, const LangOptions &LangOpts);
|
||||
void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins,
|
||||
const AnalyzerOptions &opts,
|
||||
DiagnosticsEngine &diags);
|
||||
DiagnosticsEngine &diags,
|
||||
const LangOptions &LangOpts);
|
||||
void printAnalyzerConfigList(raw_ostream &OS);
|
||||
|
||||
} // end GR namespace
|
||||
|
|
|
@ -238,7 +238,7 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
|
|||
// 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;
|
||||
}
|
||||
|
||||
|
@ -247,7 +247,8 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
|
|||
ento::printEnabledCheckerList(llvm::outs(),
|
||||
Clang->getFrontendOpts().Plugins,
|
||||
*Clang->getAnalyzerOpts(),
|
||||
Clang->getDiagnostics());
|
||||
Clang->getDiagnostics(),
|
||||
Clang->getLangOpts());
|
||||
}
|
||||
|
||||
// Honor -analyzer-config-help.
|
||||
|
|
|
@ -175,3 +175,7 @@ public:
|
|||
void ento::registerAnalysisOrderChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<AnalysisOrderChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterAnalysisOrderChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -139,3 +139,7 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
|
|||
void ento::registerAnalyzerStatsChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<AnalyzerStatsChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterAnalyzerStatsChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -90,3 +90,7 @@ void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
|
|||
void ento::registerArrayBoundChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ArrayBoundChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterArrayBoundChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -353,3 +353,7 @@ RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(ProgramStateRef state,
|
|||
void ento::registerArrayBoundCheckerV2(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ArrayBoundCheckerV2>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterArrayBoundCheckerV2(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1242,27 +1242,54 @@ void ento::registerNilArgChecker(CheckerManager &mgr) {
|
|||
mgr.registerChecker<NilArgChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterNilArgChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ento::registerCFNumberChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<CFNumberChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCFNumberChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ento::registerCFRetainReleaseChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<CFRetainReleaseChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCFRetainReleaseChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ento::registerClassReleaseChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ClassReleaseChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterClassReleaseChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ento::registerVariadicMethodTypeChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<VariadicMethodTypeChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterVariadicMethodTypeChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ento::registerObjCLoopChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ObjCLoopChecker>();
|
||||
}
|
||||
|
||||
void
|
||||
ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) {
|
||||
bool ento::shouldRegisterObjCLoopChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ObjCNonNilReturnValueChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCNonNilReturnValueChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -182,3 +182,7 @@ void BlockInCriticalSectionChecker::reportBlockInCritSection(
|
|||
void ento::registerBlockInCriticalSectionChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<BlockInCriticalSectionChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterBlockInCriticalSectionChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -154,3 +154,7 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
|
|||
void ento::registerBoolAssignmentChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<BoolAssignmentChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterBoolAssignmentChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -119,3 +119,7 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
|
|||
void ento::registerBuiltinFunctionChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<BuiltinFunctionChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterBuiltinFunctionChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2480,6 +2480,10 @@ void CStringChecker::checkDeadSymbols(SymbolReaper &SR,
|
|||
CStringChecker *checker = mgr.registerChecker<CStringChecker>(); \
|
||||
checker->Filter.Check##name = true; \
|
||||
checker->Filter.CheckName##name = mgr.getCurrentCheckName(); \
|
||||
} \
|
||||
\
|
||||
bool ento::shouldRegister##name(const LangOptions &LO) { \
|
||||
return true; \
|
||||
}
|
||||
|
||||
REGISTER_CHECKER(CStringNullArg)
|
||||
|
|
|
@ -289,3 +289,6 @@ void ento::registerCStringSyntaxChecker(CheckerManager &mgr) {
|
|||
mgr.registerChecker<CStringSyntaxChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCStringSyntaxChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -59,3 +59,7 @@ void CXXSelfAssignmentChecker::checkBeginFunction(CheckerContext &C) const {
|
|||
void ento::registerCXXSelfAssignmentChecker(CheckerManager &Mgr) {
|
||||
Mgr.registerChecker<CXXSelfAssignmentChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCXXSelfAssignmentChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -613,6 +613,10 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
|
|||
mgr.registerChecker<CallAndMessageChecker>(); \
|
||||
Checker->Filter.Check_##name = true; \
|
||||
Checker->Filter.CheckName_##name = mgr.getCurrentCheckName(); \
|
||||
} \
|
||||
\
|
||||
bool ento::shouldRegister##name(const LangOptions &LO) { \
|
||||
return true; \
|
||||
}
|
||||
|
||||
REGISTER_CHECKER(CallAndMessageUnInitRefArg)
|
||||
|
|
|
@ -139,10 +139,13 @@ void CastSizeChecker::checkPreStmt(const CastExpr *CE,CheckerContext &C) const {
|
|||
}
|
||||
|
||||
void ento::registerCastSizeChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<CastSizeChecker>();
|
||||
}
|
||||
|
||||
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<CastSizeChecker>();
|
||||
return !LO.CPlusPlus;
|
||||
}
|
||||
|
|
|
@ -119,3 +119,7 @@ public:
|
|||
void ento::registerCastToStructChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<CastToStructChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCastToStructChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1093,3 +1093,7 @@ void ento::registerObjCDeallocChecker(CheckerManager &Mgr) {
|
|||
|
||||
Mgr.registerChecker<ObjCDeallocChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCDeallocChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -137,3 +137,7 @@ public:
|
|||
void ento::registerObjCMethSigsChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ObjCMethSigsChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCMethSigsChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -911,6 +911,10 @@ public:
|
|||
mgr.registerChecker<SecuritySyntaxChecker>(); \
|
||||
checker->filter.check_##name = true; \
|
||||
checker->filter.checkName_##name = mgr.getCurrentCheckName(); \
|
||||
} \
|
||||
\
|
||||
bool ento::shouldRegister##name(const LangOptions &LO) { \
|
||||
return true; \
|
||||
}
|
||||
|
||||
REGISTER_CHECKER(bcmp)
|
||||
|
|
|
@ -90,3 +90,7 @@ public:
|
|||
void ento::registerSizeofPointerChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<SizeofPointerChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterSizeofPointerChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -152,3 +152,7 @@ void ChrootChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
|
|||
void ento::registerChrootChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ChrootChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterChrootChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -201,3 +201,7 @@ void CloneChecker::reportSuspiciousClones(
|
|||
void ento::registerCloneChecker(CheckerManager &Mgr) {
|
||||
Mgr.registerChecker<CloneChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCloneChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -195,3 +195,7 @@ bool ConversionChecker::isLossOfSign(const ImplicitCastExpr *Cast,
|
|||
void ento::registerConversionChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ConversionChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterConversionChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -478,3 +478,7 @@ public:
|
|||
void ento::registerDeadStoresChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<DeadStoresChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterDeadStoresChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,10 @@ void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
|
|||
mgr.registerChecker<DominatorsTreeDumper>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterDominatorsTreeDumper(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LiveVariablesDumper
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -67,6 +71,10 @@ void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
|
|||
mgr.registerChecker<LiveVariablesDumper>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterLiveVariablesDumper(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LiveStatementsDumper
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -86,6 +94,10 @@ void ento::registerLiveStatementsDumper(CheckerManager &mgr) {
|
|||
mgr.registerChecker<LiveStatementsDumper>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterLiveStatementsDumper(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CFGViewer
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -106,6 +118,10 @@ void ento::registerCFGViewer(CheckerManager &mgr) {
|
|||
mgr.registerChecker<CFGViewer>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCFGViewer(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CFGDumper
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -132,6 +148,10 @@ void ento::registerCFGDumper(CheckerManager &mgr) {
|
|||
mgr.registerChecker<CFGDumper>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCFGDumper(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CallGraphViewer
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -152,6 +172,10 @@ void ento::registerCallGraphViewer(CheckerManager &mgr) {
|
|||
mgr.registerChecker<CallGraphViewer>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCallGraphViewer(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CallGraphDumper
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -172,6 +196,9 @@ void ento::registerCallGraphDumper(CheckerManager &mgr) {
|
|||
mgr.registerChecker<CallGraphDumper>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCallGraphDumper(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ConfigDumper
|
||||
|
@ -213,6 +240,10 @@ void ento::registerConfigDumper(CheckerManager &mgr) {
|
|||
mgr.registerChecker<ConfigDumper>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterConfigDumper(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ExplodedGraph Viewer
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -232,3 +263,6 @@ void ento::registerExplodedGraphViewer(CheckerManager &mgr) {
|
|||
mgr.registerChecker<ExplodedGraphViewer>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterExplodedGraphViewer(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -147,3 +147,8 @@ DeleteWithNonVirtualDtorChecker::DeleteBugVisitor::VisitNode(
|
|||
void ento::registerDeleteWithNonVirtualDtorChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<DeleteWithNonVirtualDtorChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterDeleteWithNonVirtualDtorChecker(
|
||||
const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -303,3 +303,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
|
|||
void ento::registerDereferenceChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<DereferenceChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterDereferenceChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -205,12 +205,6 @@ void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator(
|
|||
}
|
||||
}
|
||||
|
||||
// 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<DirectIvarAssignment>();
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
@ -220,7 +214,22 @@ static bool AttrFilter(const ObjCMethodDecl *M) {
|
|||
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<DirectIvarAssignment>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterDirectIvarAssignment(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ento::registerDirectIvarAssignmentForAnnotatedFunctions(
|
||||
CheckerManager &mgr) {
|
||||
mgr.registerChecker<DirectIvarAssignment>()->ShouldSkipMethod = &AttrFilter;
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterDirectIvarAssignmentForAnnotatedFunctions(
|
||||
const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -98,3 +98,7 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
|
|||
void ento::registerDivZeroChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<DivZeroChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterDivZeroChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -205,3 +205,7 @@ void DynamicTypeChecker::checkPostStmt(const ImplicitCastExpr *CE,
|
|||
void ento::registerDynamicTypeChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<DynamicTypeChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterDynamicTypeChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -992,6 +992,14 @@ void ento::registerObjCGenericsChecker(CheckerManager &mgr) {
|
|||
checker->CheckGenerics = true;
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCGenericsChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ento::registerDynamicTypePropagation(CheckerManager &mgr) {
|
||||
mgr.registerChecker<DynamicTypePropagation>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterDynamicTypePropagation(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -125,3 +125,7 @@ void EnumCastOutOfRangeChecker::checkPreStmt(const CastExpr *CE,
|
|||
void ento::registerEnumCastOutOfRangeChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<EnumCastOutOfRangeChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterEnumCastOutOfRangeChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -408,3 +408,7 @@ void ExprInspectionChecker::analyzerExpress(const CallExpr *CE,
|
|||
void ento::registerExprInspectionChecker(CheckerManager &Mgr) {
|
||||
Mgr.registerChecker<ExprInspectionChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterExprInspectionChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -64,3 +64,7 @@ void FixedAddressChecker::checkPreStmt(const BinaryOperator *B,
|
|||
void ento::registerFixedAddressChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<FixedAddressChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterFixedAddressChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -221,8 +221,12 @@ void GCDAntipatternChecker::checkASTCodeBody(const Decl *D,
|
|||
emitDiagnostics(Match, "group", BR, ADC, this);
|
||||
}
|
||||
|
||||
}
|
||||
} // end of anonymous namespace
|
||||
|
||||
void ento::registerGCDAntipattern(CheckerManager &Mgr) {
|
||||
Mgr.registerChecker<GCDAntipatternChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterGCDAntipattern(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -288,11 +288,11 @@ ProgramStateRef GTestChecker::assumeValuesEqual(SVal Val1, SVal Val2,
|
|||
}
|
||||
|
||||
void ento::registerGTestChecker(CheckerManager &Mgr) {
|
||||
const LangOptions &LangOpts = Mgr.getLangOpts();
|
||||
// gtest is a C++ API so there is no sense running the checker
|
||||
// if not compiling for C++.
|
||||
if (!LangOpts.CPlusPlus)
|
||||
return;
|
||||
|
||||
Mgr.registerChecker<GTestChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterGTestChecker(const LangOptions &LO) {
|
||||
// gtest is a C++ API so there is no sense running the checker
|
||||
// if not compiling for C++.
|
||||
return LO.CPlusPlus;
|
||||
}
|
||||
|
|
|
@ -745,3 +745,7 @@ bool GenericTaintChecker::checkTaintedBufferSize(const CallExpr *CE,
|
|||
void ento::registerGenericTaintChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<GenericTaintChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterGenericTaintChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -512,3 +512,7 @@ public:
|
|||
void ento::registerIdenticalExprChecker(CheckerManager &Mgr) {
|
||||
Mgr.registerChecker<FindIdenticalExprChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterIdenticalExprChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -309,3 +309,7 @@ void ento::registerInnerPointerChecker(CheckerManager &Mgr) {
|
|||
registerInnerPointerCheckerAux(Mgr);
|
||||
Mgr.registerChecker<InnerPointerChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterInnerPointerChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2399,6 +2399,10 @@ bool compare(ProgramStateRef State, NonLoc NL1, NonLoc NL2,
|
|||
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)
|
||||
|
|
|
@ -741,6 +741,10 @@ public:
|
|||
mgr.registerChecker<IvarInvalidationChecker>(); \
|
||||
checker->Filter.check_##name = true; \
|
||||
checker->Filter.checkName_##name = mgr.getCurrentCheckName(); \
|
||||
} \
|
||||
\
|
||||
bool ento::shouldRegister##name(const LangOptions &LO) { \
|
||||
return true; \
|
||||
}
|
||||
|
||||
REGISTER_CHECKER(InstanceVariableInvalidation)
|
||||
|
|
|
@ -313,3 +313,7 @@ public:
|
|||
void ento::registerLLVMConventionsChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<LLVMConventionsChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterLLVMConventionsChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1401,10 +1401,22 @@ void ento::registerNonLocalizedStringChecker(CheckerManager &mgr) {
|
|||
false, checker);
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterNonLocalizedStringChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ento::registerEmptyLocalizationContextChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<EmptyLocalizationContextChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterEmptyLocalizationContextChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ento::registerPluralMisuseChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<PluralMisuseChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterPluralMisuseChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -187,3 +187,7 @@ void MPIChecker::allRegionsUsedByWait(
|
|||
void clang::ento::registerMPIChecker(CheckerManager &MGR) {
|
||||
MGR.registerChecker<clang::ento::mpi::MPIChecker>();
|
||||
}
|
||||
|
||||
bool clang::ento::shouldRegisterMPIChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -661,3 +661,7 @@ void MacOSKeychainAPIChecker::printState(raw_ostream &Out,
|
|||
void ento::registerMacOSKeychainAPIChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<MacOSKeychainAPIChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterMacOSKeychainAPIChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -173,3 +173,7 @@ void MacOSXAPIChecker::checkPreStmt(const CallExpr *CE,
|
|||
void ento::registerMacOSXAPIChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<MacOSXAPIChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterMacOSXAPIChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3105,6 +3105,10 @@ void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -3125,6 +3129,10 @@ void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) {
|
|||
"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)
|
||||
|
|
|
@ -333,7 +333,10 @@ void MallocOverflowSecurityChecker::checkASTCodeBody(const Decl *D,
|
|||
OutputPossibleOverflows(PossibleMallocOverflows, D, BR, mgr);
|
||||
}
|
||||
|
||||
void
|
||||
ento::registerMallocOverflowSecurityChecker(CheckerManager &mgr) {
|
||||
void ento::registerMallocOverflowSecurityChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<MallocOverflowSecurityChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterMallocOverflowSecurityChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -249,3 +249,7 @@ public:
|
|||
void ento::registerMallocSizeofChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<MallocSizeofChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterMallocSizeofChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -87,3 +87,7 @@ void ento::registerMmapWriteExecChecker(CheckerManager &mgr) {
|
|||
mgr.getAnalyzerOptions()
|
||||
.getCheckerIntegerOption("MmapProtRead", 0x01, Mwec);
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterMmapWriteExecChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -737,3 +737,7 @@ void ento::registerMoveChecker(CheckerManager &mgr) {
|
|||
chk->setAggressiveness(
|
||||
mgr.getAnalyzerOptions().getCheckerStringOption("WarnOn", "", chk));
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterMoveChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,9 @@ void NSAutoreleasePoolChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
|
|||
}
|
||||
|
||||
void ento::registerNSAutoreleasePoolChecker(CheckerManager &mgr) {
|
||||
if (mgr.getLangOpts().getGC() != LangOptions::NonGC)
|
||||
mgr.registerChecker<NSAutoreleasePoolChecker>();
|
||||
mgr.registerChecker<NSAutoreleasePoolChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterNSAutoreleasePoolChecker(const LangOptions &LO) {
|
||||
return LO.getGC() != LangOptions::NonGC;
|
||||
}
|
||||
|
|
|
@ -314,9 +314,17 @@ void ento::registerNSErrorChecker(CheckerManager &mgr) {
|
|||
checker->ShouldCheckNSError = true;
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterNSErrorChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ento::registerCFErrorChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<CFErrorFunctionChecker>();
|
||||
NSOrCFErrorDerefChecker *checker =
|
||||
mgr.registerChecker<NSOrCFErrorDerefChecker>();
|
||||
checker->ShouldCheckCFError = true;
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCFErrorChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -142,3 +142,7 @@ void NoReturnFunctionChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
|
|||
void ento::registerNoReturnFunctionChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<NoReturnFunctionChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterNoReturnFunctionChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -216,3 +216,7 @@ std::unique_ptr<BugReport> NonNullParamChecker::genReportReferenceToNullPointer(
|
|||
void ento::registerNonNullParamChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<NonNullParamChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterNonNullParamChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -137,3 +137,7 @@ bool NonnullGlobalConstantsChecker::isNonnullType(QualType Ty) const {
|
|||
void ento::registerNonnullGlobalConstantsChecker(CheckerManager &Mgr) {
|
||||
Mgr.registerChecker<NonnullGlobalConstantsChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterNonnullGlobalConstantsChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1199,8 +1199,12 @@ void NullabilityChecker::printState(raw_ostream &Out, ProgramStateRef State,
|
|||
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
|
||||
|
|
|
@ -348,3 +348,7 @@ void ento::registerNumberObjectConversionChecker(CheckerManager &Mgr) {
|
|||
Chk->Pedantic =
|
||||
Mgr.getAnalyzerOptions().getCheckerBooleanOption("Pedantic", false, Chk);
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterNumberObjectConversionChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,9 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
|
|||
}
|
||||
|
||||
void ento::registerObjCAtSyncChecker(CheckerManager &mgr) {
|
||||
if (mgr.getLangOpts().ObjC)
|
||||
mgr.registerChecker<ObjCAtSyncChecker>();
|
||||
mgr.registerChecker<ObjCAtSyncChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCAtSyncChecker(const LangOptions &LO) {
|
||||
return LO.ObjC;
|
||||
}
|
||||
|
|
|
@ -206,3 +206,7 @@ void ObjCAutoreleaseWriteChecker::checkASTCodeBody(const Decl *D,
|
|||
void ento::registerAutoreleaseWriteChecker(CheckerManager &Mgr) {
|
||||
Mgr.registerChecker<ObjCAutoreleaseWriteChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterAutoreleaseWriteChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -171,3 +171,7 @@ public:
|
|||
void ento::registerObjCContainersASTChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ObjCContainersASTChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCContainersASTChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -186,3 +186,7 @@ void ObjCContainersChecker::printState(raw_ostream &OS, ProgramStateRef State,
|
|||
void ento::registerObjCContainersChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ObjCContainersChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCContainersChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -221,6 +221,9 @@ void ento::registerObjCSuperCallChecker(CheckerManager &Mgr) {
|
|||
Mgr.registerChecker<ObjCSuperCallChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCSuperCallChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
ToDo list for expanding this check in the future, the list is not exhaustive.
|
||||
|
|
|
@ -78,3 +78,7 @@ void ObjCPropertyChecker::checkCopyMutable(const ObjCPropertyDecl *D,
|
|||
void ento::registerObjCPropertyChecker(CheckerManager &Mgr) {
|
||||
Mgr.registerChecker<ObjCPropertyChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCPropertyChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -436,3 +436,7 @@ static bool isInitMessage(const ObjCMethodCall &Call) {
|
|||
void ento::registerObjCSelfInitChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ObjCSelfInitChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCSelfInitChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -281,8 +281,9 @@ SuperDeallocBRVisitor::VisitNode(const ExplodedNode *Succ,
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void ento::registerObjCSuperDeallocChecker(CheckerManager &Mgr) {
|
||||
const LangOptions &LangOpts = Mgr.getLangOpts();
|
||||
if (LangOpts.getGC() == LangOptions::GCOnly || LangOpts.ObjCAutoRefCount)
|
||||
return;
|
||||
Mgr.registerChecker<ObjCSuperDeallocChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCSuperDeallocChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -185,3 +185,7 @@ public:
|
|||
void ento::registerObjCUnusedIvarsChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ObjCUnusedIvarsChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterObjCUnusedIvarsChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -350,3 +350,7 @@ public:
|
|||
void ento::registerPaddingChecker(CheckerManager &Mgr) {
|
||||
Mgr.registerChecker<PaddingChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterPaddingChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -342,3 +342,7 @@ void PointerArithChecker::checkPreStmt(const BinaryOperator *BOp,
|
|||
void ento::registerPointerArithChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<PointerArithChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterPointerArithChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -72,3 +72,7 @@ void PointerSubChecker::checkPreStmt(const BinaryOperator *B,
|
|||
void ento::registerPointerSubChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<PointerSubChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterPointerSubChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -480,3 +480,7 @@ void PthreadLockChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
|||
void ento::registerPthreadLockChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<PthreadLockChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterPthreadLockChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1460,6 +1460,10 @@ void ento::registerRetainCountChecker(CheckerManager &Mgr) {
|
|||
Chk->TrackObjCAndCFObjects = true;
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterRetainCountChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME: remove this, hack for backwards compatibility:
|
||||
// it should be possible to enable the NS/CF retain count checker as
|
||||
// osx.cocoa.RetainCount, and it should be possible to disable
|
||||
|
@ -1476,3 +1480,7 @@ void ento::registerOSObjectRetainCountChecker(CheckerManager &Mgr) {
|
|||
if (!hasPrevCheckOSObjectOptionDisabled(Mgr.getAnalyzerOptions()))
|
||||
Chk->TrackOSObjects = true;
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterOSObjectRetainCountChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -89,3 +89,7 @@ void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
|
|||
void ento::registerReturnPointerRangeChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ReturnPointerRangeChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterReturnPointerRangeChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -120,3 +120,7 @@ void ReturnUndefChecker::checkReference(CheckerContext &C, const Expr *RetE,
|
|||
void ento::registerReturnUndefChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<ReturnUndefChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterReturnUndefChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -202,3 +202,7 @@ void RunLoopAutoreleaseLeakChecker::checkASTCodeBody(const Decl *D,
|
|||
void ento::registerRunLoopAutoreleaseLeakChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<RunLoopAutoreleaseLeakChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterRunLoopAutoreleaseLeakChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -268,3 +268,8 @@ SimpleStreamChecker::checkPointerEscape(ProgramStateRef State,
|
|||
void ento::registerSimpleStreamChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<SimpleStreamChecker>();
|
||||
}
|
||||
|
||||
// This checker should be enabled regardless of how language options are set.
|
||||
bool ento::shouldRegisterSimpleStreamChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -364,6 +364,10 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
|
|||
StackAddrEscapeChecker *Chk = \
|
||||
Mgr.registerChecker<StackAddrEscapeChecker>(); \
|
||||
Chk->ChecksEnabled[StackAddrEscapeChecker::CK_##name] = true; \
|
||||
} \
|
||||
\
|
||||
bool ento::shouldRegister##name(const LangOptions &LO) { \
|
||||
return true; \
|
||||
}
|
||||
|
||||
REGISTER_CHECKER(StackAddrEscapeChecker)
|
||||
|
|
|
@ -1055,3 +1055,7 @@ void ento::registerStdCLibraryFunctionsChecker(CheckerManager &mgr) {
|
|||
// class, turning on different function summaries.
|
||||
mgr.registerChecker<StdLibraryFunctionsChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterStdCLibraryFunctionsChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -408,3 +408,7 @@ void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
|||
void ento::registerStreamChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<StreamChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterStreamChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -59,3 +59,7 @@ void TaintTesterChecker::checkPostStmt(const Expr *E,
|
|||
void ento::registerTaintTesterChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<TaintTesterChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterTaintTesterChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -260,3 +260,7 @@ void TestAfterDivZeroChecker::checkBranchCondition(const Stmt *Condition,
|
|||
void ento::registerTestAfterDivZeroChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<TestAfterDivZeroChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterTestAfterDivZeroChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,10 @@ void ento::registerTraversalDumper(CheckerManager &mgr) {
|
|||
mgr.registerChecker<TraversalDumper>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterTraversalDumper(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
|
@ -111,3 +115,7 @@ void CallDumper::checkPostCall(const CallEvent &Call, CheckerContext &C) const {
|
|||
void ento::registerCallDumper(CheckerManager &mgr) {
|
||||
mgr.registerChecker<CallDumper>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterCallDumper(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -248,7 +248,10 @@ private:
|
|||
|
||||
} // end empty namespace
|
||||
|
||||
|
||||
void ento::registerTrustNonnullChecker(CheckerManager &Mgr) {
|
||||
Mgr.registerChecker<TrustNonnullChecker>(Mgr.getASTContext());
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterTrustNonnullChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -108,3 +108,7 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
|
|||
void ento::registerUndefBranchChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<UndefBranchChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterUndefBranchChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -99,3 +99,7 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE,
|
|||
void ento::registerUndefCapturedBlockVarChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<UndefCapturedBlockVarChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterUndefCapturedBlockVarChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -185,3 +185,7 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
|
|||
void ento::registerUndefResultChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<UndefResultChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterUndefResultChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -61,3 +61,7 @@ UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,
|
|||
void ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<UndefinedArraySubscriptChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterUndefinedArraySubscriptChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -119,3 +119,7 @@ void UndefinedAssignmentChecker::checkBind(SVal location, SVal val,
|
|||
void ento::registerUndefinedAssignmentChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<UndefinedAssignmentChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterUndefinedAssignmentChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -535,3 +535,7 @@ void ento::registerUninitializedObjectChecker(CheckerManager &Mgr) {
|
|||
AnOpts.getCheckerStringOption("IgnoreRecordsWithField",
|
||||
/*DefaultVal*/ "", Chk);
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterUninitializedObjectChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -472,6 +472,10 @@ void UnixAPIChecker::checkPreStmt(const CallExpr *CE,
|
|||
#define REGISTER_CHECKER(Name) \
|
||||
void ento::registerUnixAPI##Name##Checker(CheckerManager &mgr) { \
|
||||
mgr.registerChecker<UnixAPIChecker>()->Check##Name = true; \
|
||||
} \
|
||||
\
|
||||
bool ento::shouldRegisterUnixAPI##Name##Checker(const LangOptions &LO) { \
|
||||
return true; \
|
||||
}
|
||||
|
||||
REGISTER_CHECKER(Misuse)
|
||||
|
|
|
@ -256,3 +256,7 @@ bool UnreachableCodeChecker::isEmptyCFGBlock(const CFGBlock *CB) {
|
|||
void ento::registerUnreachableCodeChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<UnreachableCodeChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterUnreachableCodeChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -182,3 +182,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
|
|||
void ento::registerVLASizeChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<VLASizeChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterVLASizeChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -404,6 +404,10 @@ std::shared_ptr<PathDiagnosticPiece> ValistChecker::ValistBugVisitor::VisitNode(
|
|||
ValistChecker *checker = mgr.registerChecker<ValistChecker>(); \
|
||||
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)
|
||||
|
|
|
@ -215,3 +215,7 @@ void VforkChecker::checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const {
|
|||
void ento::registerVforkChecker(CheckerManager &mgr) {
|
||||
mgr.registerChecker<VforkChecker>();
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterVforkChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -282,3 +282,7 @@ void ento::registerVirtualCallChecker(CheckerManager &mgr) {
|
|||
mgr.getAnalyzerOptions().getCheckerBooleanOption("PureOnly", false,
|
||||
checker);
|
||||
}
|
||||
|
||||
bool ento::shouldRegisterVirtualCallChecker(const LangOptions &LO) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ std::unique_ptr<CheckerManager> ento::createCheckerManager(
|
|||
DiagnosticsEngine &diags) {
|
||||
auto checkerMgr = llvm::make_unique<CheckerManager>(context, opts);
|
||||
|
||||
CheckerRegistry allCheckers(plugins, diags);
|
||||
CheckerRegistry allCheckers(plugins, diags, context.getLangOpts());
|
||||
|
||||
for (const auto &Fn : checkerRegistrationFns)
|
||||
Fn(allCheckers);
|
||||
|
@ -46,20 +46,22 @@ std::unique_ptr<CheckerManager> ento::createCheckerManager(
|
|||
}
|
||||
|
||||
void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins,
|
||||
DiagnosticsEngine &diags) {
|
||||
DiagnosticsEngine &diags,
|
||||
const LangOptions &langOpts) {
|
||||
out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
|
||||
out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";
|
||||
|
||||
CheckerRegistry(plugins, diags).printHelp(out);
|
||||
CheckerRegistry(plugins, diags, langOpts).printHelp(out);
|
||||
}
|
||||
|
||||
void ento::printEnabledCheckerList(raw_ostream &out,
|
||||
ArrayRef<std::string> 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) {
|
||||
|
|
|
@ -39,10 +39,14 @@ static bool isCompatibleAPIVersion(const char *versionString) {
|
|||
}
|
||||
|
||||
CheckerRegistry::CheckerRegistry(ArrayRef<std::string> plugins,
|
||||
DiagnosticsEngine &diags) : Diags(diags) {
|
||||
DiagnosticsEngine &diags,
|
||||
const LangOptions &LangOpts)
|
||||
: Diags(diags), LangOpts(LangOpts) {
|
||||
|
||||
#define GET_CHECKERS
|
||||
#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \
|
||||
addChecker(register##CLASS, FULLNAME, HELPTEXT, DOC_URI);
|
||||
addChecker(register##CLASS, shouldRegister##CLASS, FULLNAME, HELPTEXT, \
|
||||
DOC_URI);
|
||||
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
|
||||
#undef CHECKER
|
||||
#undef GET_CHECKERS
|
||||
|
@ -114,7 +118,8 @@ CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers(
|
|||
|
||||
for (const std::pair<std::string, bool> &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,18 +142,21 @@ CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers(
|
|||
// 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,
|
||||
void CheckerRegistry::addChecker(InitializationFunction Rfn,
|
||||
ShouldRegisterFunction Sfn, StringRef Name,
|
||||
StringRef Desc, StringRef DocsUri) {
|
||||
Checkers.emplace_back(Fn, Name, Desc, DocsUri);
|
||||
Checkers.emplace_back(Rfn, Sfn, Name, Desc, DocsUri);
|
||||
|
||||
// Record the presence of the checker in its packages.
|
||||
StringRef packageName, leafName;
|
||||
|
|
Loading…
Reference in New Issue