зеркало из https://github.com/microsoft/clang-1.git
[analyzer] Overhauling of the checker registration mechanism.
-Checkers will be defined in the tablegen file 'Checkers.td'. -Apart from checkers, we can define checker "packages" that will contain a collection of checkers. -Checkers can be enabled with -analyzer-checker=<name> and disabled with -analyzer-disable-checker=<name> e.g: Enable checkers from 'cocoa' and 'corefoundation' packages except the self-initialization checker: -analyzer-checker=cocoa -analyzer-checker=corefoundation -analyzer-disable-checker=cocoa.SelfInit -Introduces CheckerManager and CheckerProvider. CheckerProviders get the set of checker names to enable/disable and register them with the CheckerManager which will be the entry point for all checker-related functionality. Currently only the self-initialization checker takes advantage of the new mechanism. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125503 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
5f83d6f36a
Коммит
43dee22025
|
@ -270,4 +270,7 @@ def warn_unknown_warning_option : Warning<
|
|||
def warn_unknown_warning_specifier : Warning<
|
||||
"unknown %0 warning specifier: '%1'">,
|
||||
InGroup<DiagGroup<"unknown-warning-option"> >;
|
||||
|
||||
def warn_unkwown_analyzer_checker : Warning<
|
||||
"no analyzer checkers are associated with '%0'">;
|
||||
}
|
||||
|
|
|
@ -64,8 +64,6 @@ def analysis_WarnObjCUnusedIvars : Flag<"-analyzer-check-objc-unused-ivars">,
|
|||
HelpText<"Warn about private ivars that are never used">;
|
||||
def analysis_ObjCMemChecker : Flag<"-analyzer-check-objc-mem">,
|
||||
HelpText<"Run the [Core] Foundation reference count checker">;
|
||||
def analysis_WarnObjCSelfInit : Flag<"-analyzer-check-objc-self-init">,
|
||||
HelpText<"Warn about missing initialization of 'self' in an initializer">;
|
||||
def analysis_WarnSizeofPointer : Flag<"-warn-sizeof-pointer">,
|
||||
HelpText<"Warn about unintended use of sizeof() on pointer expressions">;
|
||||
def analysis_WarnIdempotentOps : Flag<"-analyzer-check-idempotent-operations">,
|
||||
|
@ -122,6 +120,16 @@ def analyzer_max_nodes : Separate<"-analyzer-max-nodes">,
|
|||
def analyzer_max_loop : Separate<"-analyzer-max-loop">,
|
||||
HelpText<"The maximum number of times the analyzer will go through a loop">;
|
||||
|
||||
def analyzer_checker : Separate<"-analyzer-checker">,
|
||||
HelpText<"Choose analyzer checkers to enable">;
|
||||
def analyzer_checker_EQ : Joined<"-analyzer-checker=">,
|
||||
Alias<analyzer_checker>;
|
||||
|
||||
def analyzer_disable_checker : Separate<"-analyzer-disable-checker">,
|
||||
HelpText<"Choose analyzer checkers to disable">;
|
||||
def analyzer_disable_checker_EQ : Joined<"-analyzer-disable-checker=">,
|
||||
Alias<analyzer_disable_checker>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CodeGen Options
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -56,6 +56,8 @@ NUM_ANALYSIS_DIAG_CLIENTS
|
|||
class AnalyzerOptions {
|
||||
public:
|
||||
std::vector<Analyses> AnalysisList;
|
||||
/// \brief Pair of checker name and enable/disable.
|
||||
std::vector<std::pair<std::string, bool> > CheckersControlList;
|
||||
AnalysisStores AnalysisStoreOpt;
|
||||
AnalysisConstraints AnalysisConstraintsOpt;
|
||||
AnalysisDiagClients AnalysisDiagOpt;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
//===--- CheckerBase.td - Checker TableGen classes ------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the TableGen core definitions for checkers
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class Package<string name> {
|
||||
string PackageName = name;
|
||||
bit Hidden = 0;
|
||||
Package ParentPackage;
|
||||
}
|
||||
class InPackage<Package P> { Package ParentPackage = P; }
|
||||
|
||||
class CheckerGroup<string name> {
|
||||
string GroupName = name;
|
||||
}
|
||||
class InGroup<CheckerGroup G> { CheckerGroup Group = G; }
|
||||
|
||||
// All checkers are an indirect subclass of this.
|
||||
class Checker<string className> {
|
||||
string ClassName = className;
|
||||
string CheckerName;
|
||||
string DescFile;
|
||||
string HelpText;
|
||||
bit Hidden = 0;
|
||||
Package ParentPackage;
|
||||
CheckerGroup Group;
|
||||
}
|
||||
|
||||
class Named<string name> { string CheckerName = name; }
|
||||
class DescFile<string filename> { string DescFile = filename; }
|
||||
class HelpText<string text> { string HelpText = text; }
|
||||
class Hidden { bit Hidden = 1; }
|
|
@ -0,0 +1,42 @@
|
|||
//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Defines the Static Analyzer Checker Manager.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
|
||||
#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace ento {
|
||||
class ExprEngine;
|
||||
|
||||
class CheckerManager {
|
||||
public:
|
||||
typedef void (*RegisterFunc)(ExprEngine &Eng);
|
||||
|
||||
void addCheckerRegisterFunction(RegisterFunc fn) {
|
||||
Funcs.push_back(fn);
|
||||
}
|
||||
|
||||
void registerCheckersToEngine(ExprEngine &eng);
|
||||
|
||||
private:
|
||||
llvm::SmallVector<RegisterFunc, 8> Funcs;
|
||||
};
|
||||
|
||||
} // end ento namespace
|
||||
|
||||
} // end clang namespace
|
||||
|
||||
#endif
|
|
@ -0,0 +1,54 @@
|
|||
//===--- CheckerProvider.h - Static Analyzer Checkers Provider --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Defines the Static Analyzer Checker Provider.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_SA_CORE_CHECKERPROVIDER_H
|
||||
#define LLVM_CLANG_SA_CORE_CHECKERPROVIDER_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace ento {
|
||||
class CheckerManager;
|
||||
|
||||
class CheckerOptInfo {
|
||||
const char *Name;
|
||||
bool Enable;
|
||||
bool Claimed;
|
||||
|
||||
public:
|
||||
CheckerOptInfo(const char *name, bool enable)
|
||||
: Name(name), Enable(enable), Claimed(false) { }
|
||||
|
||||
const char *getName() const { return Name; }
|
||||
bool isEnabled() const { return Enable; }
|
||||
bool isDisabled() const { return !isEnabled(); }
|
||||
|
||||
bool isClaimed() const { return Claimed; }
|
||||
bool isUnclaimed() const { return !isClaimed(); }
|
||||
void claim() { Claimed = true; }
|
||||
};
|
||||
|
||||
class CheckerProvider {
|
||||
public:
|
||||
virtual ~CheckerProvider();
|
||||
virtual void registerCheckers(CheckerManager &checkerMgr,
|
||||
CheckerOptInfo *checkOpts, unsigned numCheckOpts) = 0;
|
||||
};
|
||||
|
||||
} // end ento namespace
|
||||
|
||||
} // end clang namespace
|
||||
|
||||
#endif
|
|
@ -27,6 +27,7 @@ namespace idx {
|
|||
}
|
||||
|
||||
namespace ento {
|
||||
class CheckerManager;
|
||||
|
||||
class AnalysisManager : public BugReporterData {
|
||||
AnalysisContextManager AnaCtxMgr;
|
||||
|
@ -42,6 +43,8 @@ class AnalysisManager : public BugReporterData {
|
|||
StoreManagerCreator CreateStoreMgr;
|
||||
ConstraintManagerCreator CreateConstraintMgr;
|
||||
|
||||
CheckerManager *CheckerMgr;
|
||||
|
||||
/// \brief Provide function definitions in other translation units. This is
|
||||
/// NULL if we don't have multiple translation units. AnalysisManager does
|
||||
/// not own the Indexer.
|
||||
|
@ -76,6 +79,7 @@ public:
|
|||
const LangOptions &lang, PathDiagnosticClient *pd,
|
||||
StoreManagerCreator storemgr,
|
||||
ConstraintManagerCreator constraintmgr,
|
||||
CheckerManager *checkerMgr,
|
||||
idx::Indexer *idxer,
|
||||
unsigned maxnodes, unsigned maxvisit,
|
||||
bool vizdot, bool vizubi, bool purge, bool eager, bool trim,
|
||||
|
@ -85,7 +89,8 @@ public:
|
|||
|
||||
: AnaCtxMgr(useUnoptimizedCFG, addImplicitDtors, addInitializers),
|
||||
Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd),
|
||||
CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),Idxer(idxer),
|
||||
CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
|
||||
CheckerMgr(checkerMgr), Idxer(idxer),
|
||||
AScope(ScopeDecl), MaxNodes(maxnodes), MaxVisit(maxvisit),
|
||||
VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
|
||||
EagerlyAssume(eager), TrimGraph(trim), InlineCall(inlinecall),
|
||||
|
@ -110,6 +115,8 @@ public:
|
|||
return CreateConstraintMgr;
|
||||
}
|
||||
|
||||
CheckerManager *getCheckerManager() const { return CheckerMgr; }
|
||||
|
||||
idx::Indexer *getIndexer() const { return Idxer; }
|
||||
|
||||
virtual ASTContext &getASTContext() {
|
||||
|
|
|
@ -925,9 +925,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
|
||||
// Checks to perform for Objective-C/Objective-C++.
|
||||
if (types::isObjC(InputType)) {
|
||||
// Enable all checkers in 'cocoa' package.
|
||||
CmdArgs.push_back("-analyzer-checker=cocoa");
|
||||
|
||||
CmdArgs.push_back("-analyzer-check-objc-methodsigs");
|
||||
CmdArgs.push_back("-analyzer-check-objc-unused-ivars");
|
||||
CmdArgs.push_back("-analyzer-check-objc-self-init");
|
||||
// Do not enable the missing -dealloc check.
|
||||
// '-analyzer-check-objc-missing-dealloc',
|
||||
}
|
||||
|
|
|
@ -118,10 +118,17 @@ static void AnalyzerOptsToArgs(const AnalyzerOptions &Opts,
|
|||
Res.push_back("-analyzer-experimental-internal-checks");
|
||||
if (Opts.IdempotentOps)
|
||||
Res.push_back("-analyzer-check-idempotent-operations");
|
||||
if (Opts.ObjCSelfInitCheck)
|
||||
Res.push_back("-analyzer-check-objc-self-init");
|
||||
if (Opts.BufferOverflows)
|
||||
Res.push_back("-analyzer-check-buffer-overflows");
|
||||
|
||||
for (unsigned i = 0, e = Opts.CheckersControlList.size(); i != e; ++i) {
|
||||
const std::pair<std::string, bool> &opt = Opts.CheckersControlList[i];
|
||||
if (opt.second)
|
||||
Res.push_back("-analyzer-disable-checker");
|
||||
else
|
||||
Res.push_back("-analyzer-checker");
|
||||
Res.push_back(opt.first);
|
||||
}
|
||||
}
|
||||
|
||||
static void CodeGenOptsToArgs(const CodeGenOptions &Opts,
|
||||
|
@ -885,8 +892,18 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
|
|||
Opts.EagerlyTrimEGraph = !Args.hasArg(OPT_analyzer_no_eagerly_trim_egraph);
|
||||
Opts.InlineCall = Args.hasArg(OPT_analyzer_inline_call);
|
||||
Opts.IdempotentOps = Args.hasArg(OPT_analysis_WarnIdempotentOps);
|
||||
Opts.ObjCSelfInitCheck = Args.hasArg(OPT_analysis_WarnObjCSelfInit);
|
||||
Opts.BufferOverflows = Args.hasArg(OPT_analysis_WarnBufferOverflows);
|
||||
|
||||
Opts.CheckersControlList.clear();
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_analyzer_checker,
|
||||
OPT_analyzer_disable_checker),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
A->claim();
|
||||
bool enable = (A->getOption().getID() == OPT_analyzer_checker);
|
||||
Opts.CheckersControlList.push_back(std::make_pair(A->getValue(Args),
|
||||
enable));
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/FrontendTool/Utils.h"
|
||||
#include "clang/StaticAnalyzer/Core/FrontendActions.h"
|
||||
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
|
||||
#include "clang/CodeGen/CodeGenAction.h"
|
||||
#include "clang/Driver/CC1Options.h"
|
||||
#include "clang/Driver/OptTable.h"
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
set(LLVM_TARGET_DEFINITIONS Checkers.td)
|
||||
tablegen(Checkers.inc
|
||||
-gen-clang-sa-checkers
|
||||
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../../include)
|
||||
add_custom_target(ClangSACheckers
|
||||
DEPENDS Checkers.inc)
|
||||
|
||||
# So 'Checkers.inc' can be included from the cmake build directory.
|
||||
# FIXME: Someone more familiar with cmake should enable this for all of LLVM.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I ${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
set(LLVM_USED_LIBS clangBasic clangAST)
|
||||
|
||||
add_clang_library(clangStaticAnalyzerCheckers
|
||||
|
@ -17,6 +28,7 @@ add_clang_library(clangStaticAnalyzerCheckers
|
|||
CheckSecuritySyntaxOnly.cpp
|
||||
CheckSizeofPointer.cpp
|
||||
ChrootChecker.cpp
|
||||
ClangSACheckerProvider.cpp
|
||||
DeadStoresChecker.cpp
|
||||
DereferenceChecker.cpp
|
||||
DivZeroChecker.cpp
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
//===--- Checkers.td - Static Analyzer Checkers -===-----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "clang/StaticAnalyzer/Checkers/CheckerBase.td"
|
||||
|
||||
def Cocoa : Package<"cocoa">;
|
||||
|
||||
def : Checker<"ObjCSelfInitChecker">,
|
||||
InPackage<Cocoa>,
|
||||
Named<"SelfInit">,
|
||||
HelpText<"Check that 'self' is propely initialized inside an initializer method">,
|
||||
DescFile<"ObjCSelfInitChecker.cpp">;
|
|
@ -0,0 +1,135 @@
|
|||
//===--- ClangSACheckerProvider.cpp - Clang SA Checkers Provider ----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Defines the CheckerProvider for the checkers defined in
|
||||
// libclangStaticAnalyzerCheckers.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ClangSACheckerProvider.h"
|
||||
#include "ClangSACheckers.h"
|
||||
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
|
||||
#include "clang/StaticAnalyzer/Core/CheckerProvider.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace ento;
|
||||
|
||||
namespace {
|
||||
|
||||
/// \brief Provider for all the checkers in libclangStaticAnalyzerCheckers.
|
||||
class ClangSACheckerProvider : public CheckerProvider {
|
||||
public:
|
||||
virtual void registerCheckers(CheckerManager &checkerMgr,
|
||||
CheckerOptInfo *checkOpts, unsigned numCheckOpts);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
CheckerProvider *ento::createClangSACheckerProvider() {
|
||||
return new ClangSACheckerProvider();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct StaticCheckerInfoRec {
|
||||
const char *FullName;
|
||||
CheckerManager::RegisterFunc RegFunc;
|
||||
bool Hidden;
|
||||
};
|
||||
|
||||
} // end anonymous namespace.
|
||||
|
||||
static const StaticCheckerInfoRec StaticCheckerInfo[] = {
|
||||
#define GET_CHECKERS
|
||||
#define CHECKER(FULLNAME,CLASS,DESCFILE,HELPTEXT,HIDDEN) \
|
||||
{ FULLNAME, register##CLASS, HIDDEN },
|
||||
#include "Checkers.inc"
|
||||
{ 0, 0, 0}
|
||||
#undef CHECKER
|
||||
#undef GET_CHECKERS
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
struct CheckNameOption {
|
||||
const char *Name;
|
||||
const short *Members;
|
||||
const short *SubGroups;
|
||||
};
|
||||
|
||||
} // end anonymous namespace.
|
||||
|
||||
#define GET_MEMBER_ARRAYS
|
||||
#include "Checkers.inc"
|
||||
#undef GET_MEMBER_ARRAYS
|
||||
|
||||
// The table of check name options, sorted by name for fast binary lookup.
|
||||
static const CheckNameOption CheckNameTable[] = {
|
||||
#define GET_CHECKNAME_TABLE
|
||||
#include "Checkers.inc"
|
||||
#undef GET_CHECKNAME_TABLE
|
||||
};
|
||||
static const size_t
|
||||
CheckNameTableSize = sizeof(CheckNameTable) / sizeof(CheckNameTable[0]);
|
||||
|
||||
static bool CheckNameOptionCompare(const CheckNameOption &LHS,
|
||||
const CheckNameOption &RHS) {
|
||||
return strcmp(LHS.Name, RHS.Name) < 0;
|
||||
}
|
||||
|
||||
static void collectCheckers(const CheckNameOption *checkName,
|
||||
bool enable,
|
||||
llvm::DenseSet<const StaticCheckerInfoRec *> &checkers,
|
||||
bool collectHidden) {
|
||||
if (const short *member = checkName->Members) {
|
||||
if (enable) {
|
||||
if (collectHidden || !StaticCheckerInfo[*member].Hidden)
|
||||
checkers.insert(&StaticCheckerInfo[*member]);
|
||||
} else {
|
||||
for (; *member != -1; ++member)
|
||||
checkers.erase(&StaticCheckerInfo[*member]);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable/disable all subgroups along with this one.
|
||||
if (const short *subGroups = checkName->SubGroups) {
|
||||
for (; *subGroups != -1; ++subGroups)
|
||||
collectCheckers(&CheckNameTable[*subGroups], enable, checkers,
|
||||
/*don't enable hidden in subgroups*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
static void collectCheckers(CheckerOptInfo &opt,
|
||||
llvm::DenseSet<const StaticCheckerInfoRec *> &checkers) {
|
||||
const char *optName = opt.getName();
|
||||
CheckNameOption key = { optName, 0, 0 };
|
||||
const CheckNameOption *found =
|
||||
std::lower_bound(CheckNameTable, CheckNameTable + CheckNameTableSize, key,
|
||||
CheckNameOptionCompare);
|
||||
if (found == CheckNameTable + CheckNameTableSize ||
|
||||
strcmp(found->Name, optName) != 0)
|
||||
return; // Check name not found.
|
||||
|
||||
opt.claim();
|
||||
collectCheckers(found, opt.isEnabled(), checkers, /*collectHidden=*/true);
|
||||
}
|
||||
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
void ClangSACheckerProvider::registerCheckers(CheckerManager &checkerMgr,
|
||||
CheckerOptInfo *checkOpts, unsigned numCheckOpts) {
|
||||
llvm::DenseSet<const StaticCheckerInfoRec *> enabledCheckers;
|
||||
for (unsigned i = 0; i != numCheckOpts; ++i)
|
||||
collectCheckers(checkOpts[i], enabledCheckers);
|
||||
for (llvm::DenseSet<const StaticCheckerInfoRec *>::iterator
|
||||
I = enabledCheckers.begin(), E = enabledCheckers.end(); I != E; ++I) {
|
||||
checkerMgr.addCheckerRegisterFunction((*I)->RegFunc);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
//===--- ClangSACheckerProvider.h - Clang SA Checkers Provider --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Defines the entry point for creating the provider for the checkers defined
|
||||
// in libclangStaticAnalyzerCheckers.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_SA_CHECKERS_CLANGSACHECKERPROVIDER_H
|
||||
#define LLVM_CLANG_SA_CHECKERS_CLANGSACHECKERPROVIDER_H
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace ento {
|
||||
class CheckerProvider;
|
||||
|
||||
CheckerProvider *createClangSACheckerProvider();
|
||||
|
||||
} // end ento namespace
|
||||
|
||||
} // end clang namespace
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
//===--- ClangSACheckers.h - Registration functions for Checkers *- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Declares the registation functions for the checkers defined in
|
||||
// libclangStaticAnalyzerCheckers.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_SA_LIB_CHECKERS_CLANGSACHECKERS_H
|
||||
#define LLVM_CLANG_SA_LIB_CHECKERS_CLANGSACHECKERS_H
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace ento {
|
||||
class ExprEngine;
|
||||
|
||||
#define GET_CHECKERS
|
||||
#define CHECKER(FULLNAME,CLASS,CXXFILE,HELPTEXT,HIDDEN) \
|
||||
void register##CLASS(ExprEngine &Eng);
|
||||
#include "Checkers.inc"
|
||||
#undef CHECKER
|
||||
#undef GET_CHECKERS
|
||||
|
||||
} // end ento namespace
|
||||
|
||||
} // end clang namespace
|
||||
|
||||
#endif
|
|
@ -16,6 +16,7 @@
|
|||
// FIXME: Restructure checker registration.
|
||||
#include "InternalChecks.h"
|
||||
|
||||
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
|
||||
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
|
||||
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
|
||||
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
|
||||
|
@ -332,6 +333,7 @@ ExprEngine::ExprEngine(AnalysisManager &mgr, TransferFuncs *tf)
|
|||
NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
|
||||
RaiseSel(GetNullarySelector("raise", getContext())),
|
||||
BR(mgr, *this), TF(tf) {
|
||||
mgr.getCheckerManager()->registerCheckersToEngine(*this);
|
||||
// Register internal checks.
|
||||
RegisterInternalChecks(*this);
|
||||
|
||||
|
|
|
@ -14,4 +14,11 @@
|
|||
CLANG_LEVEL := ../../..
|
||||
LIBRARYNAME := clangStaticAnalyzerCheckers
|
||||
|
||||
BUILT_SOURCES = Checkers.inc
|
||||
TABLEGEN_INC_FILES_COMMON = 1
|
||||
|
||||
include $(CLANG_LEVEL)/Makefile
|
||||
|
||||
$(ObjDir)/Checkers.inc.tmp : Checkers.td $(TBLGEN) $(ObjDir)/.dir
|
||||
$(Echo) "Building Clang SA Checkers tables with tblgen"
|
||||
$(Verb) $(TableGen) -gen-clang-sa-checkers -I $(PROJ_SRC_DIR)/$(CLANG_LEVEL)/include -o $(call SYSPATH, $@) $<
|
||||
|
|
|
@ -13,6 +13,7 @@ add_clang_library(clangStaticAnalyzerCore
|
|||
CFRefCount.cpp
|
||||
Checker.cpp
|
||||
CheckerHelpers.cpp
|
||||
CheckerManager.cpp
|
||||
Environment.cpp
|
||||
ExplodedGraph.cpp
|
||||
FlatStore.cpp
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
//===--- CheckerManager.cpp - Static Analyzer Checker Manager -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Defines the Static Analyzer Checker Manager.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
|
||||
#include "clang/StaticAnalyzer/Core/CheckerProvider.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace ento;
|
||||
|
||||
void CheckerManager::registerCheckersToEngine(ExprEngine &eng) {
|
||||
for (unsigned i = 0, e = Funcs.size(); i != e; ++i)
|
||||
Funcs[i](eng);
|
||||
}
|
||||
|
||||
// Anchor for the vtable.
|
||||
CheckerProvider::~CheckerProvider() { }
|
|
@ -773,6 +773,7 @@ void CallEnterNodeBuilder::generateNode(const GRState *state) {
|
|||
OldMgr.getPathDiagnosticClient(),
|
||||
OldMgr.getStoreManagerCreator(),
|
||||
OldMgr.getConstraintManagerCreator(),
|
||||
OldMgr.getCheckerManager(),
|
||||
OldMgr.getIndexer(),
|
||||
OldMgr.getMaxNodes(), OldMgr.getMaxVisit(),
|
||||
OldMgr.shouldVisualizeGraphviz(),
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "clang/Analysis/Analyses/LiveVariables.h"
|
||||
#include "clang/Analysis/Analyses/UninitializedValues.h"
|
||||
#include "clang/Analysis/CFG.h"
|
||||
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
|
||||
#include "clang/StaticAnalyzer/Checkers/LocalCheckers.h"
|
||||
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
|
||||
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
|
||||
|
@ -92,6 +93,7 @@ public:
|
|||
StoreManagerCreator CreateStoreMgr;
|
||||
ConstraintManagerCreator CreateConstraintMgr;
|
||||
|
||||
llvm::OwningPtr<CheckerManager> checkerMgr;
|
||||
llvm::OwningPtr<AnalysisManager> Mgr;
|
||||
|
||||
AnalysisConsumer(const Preprocessor& pp,
|
||||
|
@ -175,9 +177,11 @@ public:
|
|||
|
||||
virtual void Initialize(ASTContext &Context) {
|
||||
Ctx = &Context;
|
||||
checkerMgr.reset(registerCheckers(Opts, PP.getDiagnostics()));
|
||||
Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(),
|
||||
PP.getLangOptions(), PD,
|
||||
CreateStoreMgr, CreateConstraintMgr,
|
||||
checkerMgr.get(),
|
||||
/* Indexer */ 0,
|
||||
Opts.MaxNodes, Opts.MaxLoop,
|
||||
Opts.VisualizeEGDot, Opts.VisualizeEGUbi,
|
||||
|
|
|
@ -22,8 +22,10 @@ namespace clang {
|
|||
class AnalyzerOptions;
|
||||
class ASTConsumer;
|
||||
class Preprocessor;
|
||||
class Diagnostic;
|
||||
|
||||
namespace ento {
|
||||
class CheckerManager;
|
||||
|
||||
/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
|
||||
/// analysis passes. (The set of analyses run is controlled by command-line
|
||||
|
@ -32,6 +34,8 @@ ASTConsumer* CreateAnalysisConsumer(const Preprocessor &pp,
|
|||
const std::string &output,
|
||||
const AnalyzerOptions& Opts);
|
||||
|
||||
CheckerManager *registerCheckers(const AnalyzerOptions &opts,Diagnostic &diags);
|
||||
|
||||
} // end GR namespace
|
||||
|
||||
} // end clang namespace
|
||||
|
|
|
@ -4,6 +4,7 @@ set(LLVM_USED_LIBS clangBasic clangLex clangAST clangFrontend clangRewrite)
|
|||
|
||||
add_clang_library(clangStaticAnalyzerFrontend
|
||||
AnalysisConsumer.cpp
|
||||
CheckerRegistration.cpp
|
||||
FrontendActions.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
//===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Defines the registration function for the analyzer checkers.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AnalysisConsumer.h"
|
||||
#include "../Checkers/ClangSACheckerProvider.h"
|
||||
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
|
||||
#include "clang/StaticAnalyzer/Core/CheckerProvider.h"
|
||||
#include "clang/Frontend/AnalyzerOptions.h"
|
||||
#include "clang/Frontend/FrontendDiagnostic.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace ento;
|
||||
|
||||
CheckerManager *ento::registerCheckers(const AnalyzerOptions &opts,
|
||||
Diagnostic &diags) {
|
||||
llvm::OwningPtr<CheckerManager> checkerMgr(new CheckerManager());
|
||||
|
||||
llvm::SmallVector<CheckerOptInfo, 8> checkerOpts;
|
||||
for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) {
|
||||
const std::pair<std::string, bool> &opt = opts.CheckersControlList[i];
|
||||
checkerOpts.push_back(CheckerOptInfo(opt.first.c_str(), opt.second));
|
||||
}
|
||||
|
||||
llvm::OwningPtr<CheckerProvider> provider(createClangSACheckerProvider());
|
||||
provider->registerCheckers(*checkerMgr,
|
||||
checkerOpts.data(), checkerOpts.size());
|
||||
|
||||
// FIXME: Load CheckerProviders from plugins.
|
||||
|
||||
for (unsigned i = 0, e = checkerOpts.size(); i != e; ++i) {
|
||||
if (checkerOpts[i].isUnclaimed())
|
||||
diags.Report(diag::warn_unkwown_analyzer_checker)
|
||||
<< checkerOpts[i].getName();
|
||||
}
|
||||
|
||||
return checkerMgr.take();
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/StaticAnalyzer/Core/FrontendActions.h"
|
||||
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "AnalysisConsumer.h"
|
||||
using namespace clang;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-check-objc-self-init %s -verify
|
||||
// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-checker=cocoa.SelfInit %s -verify
|
||||
|
||||
@class NSZone, NSCoder;
|
||||
@protocol NSObject
|
||||
|
|
Загрузка…
Ссылка в новой задаче