Skip to content
Merged
63 changes: 29 additions & 34 deletions clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,29 @@
// function clang_registerCheckers. For example:
//
// extern "C"
// void clang_registerCheckers (CheckerRegistry &registry) {
// registry.addChecker<MainCallChecker>("example.MainCallChecker",
// "Disallows calls to functions called main");
// void clang_registerCheckers(CheckerRegistry &Registry) {
// Registry.addChecker<MainCallChecker>(
// "example.MainCallChecker",
// "Disallows calls to functions called main");
// }
//
// The first method argument is the full name of the checker, including its
// enclosing package. By convention, the registered name of a checker is the
// name of the associated class (the template argument).
// The second method argument is a short human-readable description of the
// checker.
// The first argument of this templated method is the full name of the checker
// (including its package), while the second argument is a short description
// that is printed by `-analyzer-checker-help`.
//
// The clang_registerCheckers function may add any number of checkers to the
// registry. If any checkers require additional initialization, use the three-
// argument form of CheckerRegistry::addChecker.
// A plugin may register several separate checkers by calling `addChecker()`
// multiple times. If a checker requires custom registration functions (e.g.
// checker option handling) use the non-templated overload of `addChecker` that
// takes two callback functions as the first two parameters.
//
// To load a checker plugin, specify the full path to the dynamic library as
// the argument to the -load option in the cc1 frontend. You can then enable
// your custom checker using the -analyzer-checker:
//
// clang -cc1 -load </path/to/plugin.dylib> -analyze
// -analyzer-checker=<example.MainCallChecker>
// clang -cc1 -load /path/to/plugin.dylib -analyze
// -analyzer-checker=example.MainCallChecker
//
// For a complete working example, see examples/analyzer-plugin.
// For complete examples, see clang/lib/Analysis/plugins/SampleAnalyzer

#ifndef CLANG_ANALYZER_API_VERSION_STRING
// FIXME: The Clang version string is not particularly granular;
Expand Down Expand Up @@ -108,30 +108,25 @@ class CheckerRegistry {
mgr.template registerChecker<T>();
}

template <typename T> static bool returnTrue(const CheckerManager &mgr) {
return true;
}
static bool returnTrue(const CheckerManager &) { return true; }

public:
/// Adds a checker to the registry. Use this non-templated overload when your
/// checker requires custom initialization.
void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction sfn,
StringRef FullName, StringRef Desc, StringRef DocsUri,
bool IsHidden);

/// Adds a checker to the registry. Use this templated overload when your
/// checker does not require any custom initialization.
/// This function isn't really needed and probably causes more headaches than
/// the tiny convenience that it provides, but external plugins might use it,
/// and there isn't a strong incentive to remove it.
/// Adds a checker to the registry.
/// Use this for a checker defined in a plugin if it requires custom
/// registration functions (e.g. for handling checker options).
/// NOTE: As of now `DocsUri` is never queried from the checker registry.
void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction Sfn,
StringRef FullName, StringRef Desc,
StringRef DocsUri = "NoDocsUri", bool IsHidden = false);

/// Adds a checker to the registry.
/// Use this for a checker defined in a plugin if it doesn't require custom
/// registration functions.
template <class T>
void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri,
bool IsHidden = false) {
// Avoid MSVC's Compiler Error C2276:
// http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
void addChecker(StringRef FullName, StringRef Desc,
StringRef DocsUri = "NoDocsUri", bool IsHidden = false) {
addChecker(&CheckerRegistry::initializeManager<CheckerManager, T>,
&CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri,
IsHidden);
&CheckerRegistry::returnTrue, FullName, Desc, DocsUri, IsHidden);
}

/// Makes the checker with the full name \p fullName depend on the checker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"

// This barebones plugin is used by clang/test/Analysis/checker-plugins.c
// to test dependency handling among checkers loaded from plugins.

using namespace clang;
using namespace ento;

Expand All @@ -15,12 +18,12 @@ struct DependendentChecker : public Checker<check::BeginFunction> {
} // end anonymous namespace

// Register plugin!
extern "C" void clang_registerCheckers(CheckerRegistry &registry) {
registry.addChecker<Dependency>("example.Dependency", "", "");
registry.addChecker<DependendentChecker>("example.DependendentChecker", "",
"");
extern "C" void clang_registerCheckers(CheckerRegistry &Registry) {
Registry.addChecker<Dependency>("example.Dependency", "MockDescription");
Registry.addChecker<DependendentChecker>("example.DependendentChecker",
"MockDescription");

registry.addDependency("example.DependendentChecker", "example.Dependency");
Registry.addDependency("example.DependendentChecker", "example.Dependency");
}

extern "C" const char clang_analyzerAPIVersionString[] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
using namespace clang;
using namespace ento;

// This barebones plugin is used by clang/test/Analysis/checker-plugins.c
// to test option handling on checkers loaded from plugins.

namespace {
struct MyChecker : public Checker<check::BeginFunction> {
void checkBeginFunction(CheckerContext &Ctx) const {}
Expand All @@ -25,13 +28,11 @@ bool shouldRegisterMyChecker(const CheckerManager &mgr) { return true; }
} // end anonymous namespace

// Register plugin!
extern "C" void clang_registerCheckers(CheckerRegistry &registry) {
registry.addChecker(registerMyChecker, shouldRegisterMyChecker,
"example.MyChecker", "Example Description",
"example.mychecker.documentation.nonexistent.html",
/*isHidden*/false);
extern "C" void clang_registerCheckers(CheckerRegistry &Registry) {
Registry.addChecker(registerMyChecker, shouldRegisterMyChecker,
"example.MyChecker", "Example Description");

registry.addCheckerOption(/*OptionType*/ "bool",
Registry.addCheckerOption(/*OptionType*/ "bool",
/*CheckerFullName*/ "example.MyChecker",
/*OptionName*/ "ExampleOption",
/*DefaultValStr*/ "false",
Expand Down
18 changes: 9 additions & 9 deletions clang/lib/Analysis/plugins/SampleAnalyzer/MainCallChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"

// This simple plugin is used by clang/test/Analysis/checker-plugins.c
// to test the use of a checker that is defined in a plugin.

using namespace clang;
using namespace ento;

namespace {
class MainCallChecker : public Checker<check::PreStmt<CallExpr>> {
mutable std::unique_ptr<BugType> BT;

const BugType BT{this, "call to main", "example analyzer plugin"};

public:
void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
Expand All @@ -33,21 +37,17 @@ void MainCallChecker::checkPreStmt(const CallExpr *CE,
if (!N)
return;

if (!BT)
BT.reset(new BugType(this, "call to main", "example analyzer plugin"));

auto report =
std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
std::make_unique<PathSensitiveBugReport>(BT, BT.getDescription(), N);
report->addRange(Callee->getSourceRange());
C.emitReport(std::move(report));
}
}

// Register plugin!
extern "C" void clang_registerCheckers(CheckerRegistry &registry) {
registry.addChecker<MainCallChecker>(
"example.MainCallChecker", "Disallows calls to functions called main",
"");
extern "C" void clang_registerCheckers(CheckerRegistry &Registry) {
Registry.addChecker<MainCallChecker>("example.MainCallChecker",
"Example Description");
}

extern "C" const char clang_analyzerAPIVersionString[] =
Expand Down
6 changes: 2 additions & 4 deletions clang/unittests/StaticAnalyzer/BlockEntranceCallbackTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ void addBlockEntranceTester(AnalysisASTConsumer &AnalysisConsumer,
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker(&registerChecker<BlockEntranceCallbackTester>,
&shouldAlwaysRegister, "test.BlockEntranceTester",
"EmptyDescription", "EmptyDocsUri",
/*IsHidden=*/false);
"EmptyDescription");
});
}

Expand All @@ -102,8 +101,7 @@ void addBranchConditionTester(AnalysisASTConsumer &AnalysisConsumer,
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker(&registerChecker<BranchConditionCallbackTester>,
&shouldAlwaysRegister, "test.BranchConditionTester",
"EmptyDescription", "EmptyDocsUri",
/*IsHidden=*/false);
"EmptyDescription");
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class TestAction : public ASTFrontendAction {
std::move(ExpectedDiags), Compiler.getSourceManager()));
AnalysisConsumer->AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<InterestingnessTestChecker>("test.Interestingness",
"Description", "");
"MockDescription");
});
Compiler.getAnalyzerOpts().CheckersAndPackages = {
{"test.Interestingness", true}};
Expand Down
4 changes: 2 additions & 2 deletions clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,8 @@ void addCallDescChecker(AnalysisASTConsumer &AnalysisConsumer,
AnalyzerOptions &AnOpts) {
AnOpts.CheckersAndPackages = {{"test.CallDescChecker", true}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<CallDescChecker>("test.CallDescChecker", "Description",
"");
Registry.addChecker<CallDescChecker>("test.CallDescChecker",
"MockDescription");
});
}

Expand Down
2 changes: 1 addition & 1 deletion clang/unittests/StaticAnalyzer/CallEventTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void addCXXDeallocatorChecker(AnalysisASTConsumer &AnalysisConsumer,
AnOpts.CheckersAndPackages = {{"test.CXXDeallocator", true}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<CXXDeallocatorChecker>("test.CXXDeallocator",
"Description", "");
"MockDescription");
});
}

Expand Down
6 changes: 2 additions & 4 deletions clang/unittests/StaticAnalyzer/ConflictingEvalCallsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ void addEvalFooCheckers(AnalysisASTConsumer &AnalysisConsumer,
AnOpts.CheckersAndPackages = {{"test.EvalFoo1", true},
{"test.EvalFoo2", true}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<EvalCallFoo1>("test.EvalFoo1", "EmptyDescription",
"EmptyDocsUri");
Registry.addChecker<EvalCallFoo2>("test.EvalFoo2", "EmptyDescription",
"EmptyDocsUri");
Registry.addChecker<EvalCallFoo1>("test.EvalFoo1", "MockDescription");
Registry.addChecker<EvalCallFoo2>("test.EvalFoo2", "MockDescription");
});
}
} // namespace
Expand Down
8 changes: 4 additions & 4 deletions clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void addExprEngineVisitPreChecker(AnalysisASTConsumer &AnalysisConsumer,
AnOpts.CheckersAndPackages = {{"ExprEngineVisitPreChecker", true}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<ExprEngineVisitPreChecker>("ExprEngineVisitPreChecker",
"Desc", "DocsURI");
"MockDescription");
});
}

Expand All @@ -87,16 +87,16 @@ void addExprEngineVisitPostChecker(AnalysisASTConsumer &AnalysisConsumer,
AnOpts.CheckersAndPackages = {{"ExprEngineVisitPostChecker", true}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<ExprEngineVisitPostChecker>(
"ExprEngineVisitPostChecker", "Desc", "DocsURI");
"ExprEngineVisitPostChecker", "MockDescription");
});
}

void addMemAccessChecker(AnalysisASTConsumer &AnalysisConsumer,
AnalyzerOptions &AnOpts) {
AnOpts.CheckersAndPackages = {{"MemAccessChecker", true}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<MemAccessChecker>("MemAccessChecker", "Desc",
"DocsURI");
Registry.addChecker<MemAccessChecker>("MemAccessChecker",
"MockDescription");
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ void addFalsePositiveGenerator(AnalysisASTConsumer &AnalysisConsumer,
AnOpts.CheckersAndPackages = {{"test.FalsePositiveGenerator", true},
{"debug.ViewExplodedGraph", false}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<FalsePositiveGenerator>(
"test.FalsePositiveGenerator", "EmptyDescription", "EmptyDocsUri");
Registry.addChecker<FalsePositiveGenerator>("test.FalsePositiveGenerator",
"MockDescription");
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void addDescriptiveNameChecker(AnalysisASTConsumer &AnalysisConsumer,
AnOpts.CheckersAndPackages = {{"DescriptiveNameChecker", true}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<DescriptiveNameChecker>("DescriptiveNameChecker",
"Desc", "DocsURI");
"MockDescription");
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ void addNonThoroughStatefulChecker(AnalysisASTConsumer &AnalysisConsumer,
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry
.addChecker<StatefulChecker<NonThoroughErrorNotPreventedFuncVisitor>>(
"test.StatefulChecker", "Description", "");
"test.StatefulChecker", "MockDescription");
});
}

Expand Down Expand Up @@ -233,7 +233,7 @@ void addThoroughStatefulChecker(AnalysisASTConsumer &AnalysisConsumer,
AnOpts.CheckersAndPackages = {{"test.StatefulChecker", true}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<StatefulChecker<ThoroughErrorNotPreventedFuncVisitor>>(
"test.StatefulChecker", "Description", "");
"test.StatefulChecker", "MockDescription");
});
}

Expand Down
2 changes: 1 addition & 1 deletion clang/unittests/StaticAnalyzer/ObjcBug-124477.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void addFlagFlipperChecker(AnalysisASTConsumer &AnalysisConsumer,
AnOpts.CheckersAndPackages = {{"test.FlipFlagOnCheckLocation", true}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<FlipFlagOnCheckLocation>("test.FlipFlagOnCheckLocation",
"Description", "");
"MockDescription");
});
}

Expand Down
Loading
Loading