/// diagnostic. It represents an ordered-collection of PathDiagnosticPieces,
/// each which represent the pieces of the path.
class PathDiagnostic : public llvm::FoldingSetNode {
- std::string CheckName;
+ std::string CheckerName;
const Decl *DeclWithIssue;
std::string BugType;
std::string VerboseDesc;
public:
PathDiagnostic() = delete;
- PathDiagnostic(StringRef CheckName, const Decl *DeclWithIssue,
+ PathDiagnostic(StringRef CheckerName, const Decl *DeclWithIssue,
StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
StringRef category, PathDiagnosticLocation LocationToUnique,
const Decl *DeclToUnique,
return ShortDesc.empty() ? VerboseDesc : ShortDesc;
}
- StringRef getCheckName() const { return CheckName; }
+ StringRef getCheckerName() const { return CheckerName; }
StringRef getBugType() const { return BugType; }
StringRef getCategory() const { return Category; }
public:
using ConfigTable = llvm::StringMap<std::string>;
+ /// Retrieves the list of checkers generated from Checkers.td. This doesn't
+ /// contain statically linked but non-generated checkers and plugin checkers!
static std::vector<StringRef>
- getRegisteredCheckers(bool IncludeExperimental = false) {
- static const StringRef StaticAnalyzerChecks[] = {
-#define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) FULLNAME,
-#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
-#undef CHECKER
-#undef GET_CHECKERS
- };
- std::vector<StringRef> Checkers;
- for (StringRef CheckerName : StaticAnalyzerChecks) {
- if (!CheckerName.startswith("debug.") &&
- (IncludeExperimental || !CheckerName.startswith("alpha.")))
- Checkers.push_back(CheckerName);
- }
- return Checkers;
- }
+ getRegisteredCheckers(bool IncludeExperimental = false);
+ /// Retrieves the list of packages generated from Checkers.td. This doesn't
+ /// contain statically linked but non-generated packages and plugin packages!
static std::vector<StringRef>
- getRegisteredPackages(bool IncludeExperimental = false) {
- static const StringRef StaticAnalyzerPackages[] = {
-#define GET_PACKAGES
-#define PACKAGE(FULLNAME) FULLNAME,
-#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
-#undef PACKAGE
-#undef GET_PACKAGES
- };
- std::vector<StringRef> Packages;
- for (StringRef PackageName : StaticAnalyzerPackages) {
- if (PackageName != "debug" &&
- (IncludeExperimental || PackageName != "alpha"))
- Packages.push_back(PackageName);
- }
- return Packages;
- }
+ getRegisteredPackages(bool IncludeExperimental = false);
/// Convenience function for printing options or checkers and their
/// description in a formatted manner. If \p MinLineWidth is set to 0, no line
/// The maximum number of times the analyzer visits a block.
unsigned maxBlockVisitOnPath;
- /// Disable all analyzer checks.
+ /// Disable all analyzer checkers.
///
- /// This flag allows one to disable analyzer checks on the code processed by
+ /// This flag allows one to disable analyzer checkers on the code processed by
/// the given analysis consumer. Note, the code will get parsed and the
/// command-line options will get checked.
- unsigned DisableAllChecks : 1;
+ unsigned DisableAllCheckers : 1;
unsigned ShowCheckerHelp : 1;
unsigned ShowCheckerHelpAlpha : 1;
}
AnalyzerOptions()
- : DisableAllChecks(false), ShowCheckerHelp(false),
+ : DisableAllCheckers(false), ShowCheckerHelp(false),
ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false),
ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false),
ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
/// If an option value is not provided, returns the given \p DefaultVal.
/// @param [in] CheckerName The *full name* of the checker. One may retrieve
/// this from the checker object's field \c Name, or through \c
- /// CheckerManager::getCurrentCheckName within the checker's registry
+ /// CheckerManager::getCurrentCheckerName within the checker's registry
/// function.
/// Checker options are retrieved in the following format:
/// `-analyzer-config CheckerName:OptionName=Value.
/// If an option value is not provided, returns the given \p DefaultVal.
/// @param [in] CheckerName The *full name* of the checker. One may retrieve
/// this from the checker object's field \c Name, or through \c
- /// CheckerManager::getCurrentCheckName within the checker's registry
+ /// CheckerManager::getCurrentCheckerName within the checker's registry
/// function.
/// Checker options are retrieved in the following format:
/// `-analyzer-config CheckerName:OptionName=Value.
/// If an option value is not provided, returns the given \p DefaultVal.
/// @param [in] CheckerName The *full name* of the checker. One may retrieve
/// this from the checker object's field \c Name, or through \c
- /// CheckerManager::getCurrentCheckName within the checker's registry
+ /// CheckerManager::getCurrentCheckerName within the checker's registry
/// function.
/// Checker options are retrieved in the following format:
/// `-analyzer-config CheckerName:OptionName=Value.
return K.getValue();
}
+inline std::vector<StringRef>
+AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) {
+ static const StringRef StaticAnalyzerCheckerNames[] = {
+#define GET_CHECKERS
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) FULLNAME,
+#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+#undef CHECKER
+#undef GET_CHECKERS
+ };
+ std::vector<StringRef> Checkers;
+ for (StringRef CheckerName : StaticAnalyzerCheckerNames) {
+ if (!CheckerName.startswith("debug.") &&
+ (IncludeExperimental || !CheckerName.startswith("alpha.")))
+ Checkers.push_back(CheckerName);
+ }
+ return Checkers;
+}
+
+inline std::vector<StringRef>
+AnalyzerOptions::getRegisteredPackages(bool IncludeExperimental) {
+ static const StringRef StaticAnalyzerPackageNames[] = {
+#define GET_PACKAGES
+#define PACKAGE(FULLNAME) FULLNAME,
+#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+#undef PACKAGE
+#undef GET_PACKAGES
+ };
+ std::vector<StringRef> Packages;
+ for (StringRef PackageName : StaticAnalyzerPackageNames) {
+ if (PackageName != "debug" &&
+ (IncludeExperimental || PackageName != "alpha"))
+ Packages.push_back(PackageName);
+ }
+ return Packages;
+}
+
} // namespace clang
#endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
ArrayRef<SourceRange> Ranges = None,
ArrayRef<FixItHint> Fixits = None);
- void EmitBasicReport(const Decl *DeclWithIssue, CheckName CheckName,
+ void EmitBasicReport(const Decl *DeclWithIssue, CheckerNameRef CheckerName,
StringRef BugName, StringRef BugCategory,
StringRef BugStr, PathDiagnosticLocation Loc,
ArrayRef<SourceRange> Ranges = None,
/// Returns a BugType that is associated with the given name and
/// category.
- BugType *getBugTypeForName(CheckName CheckName, StringRef name,
+ BugType *getBugTypeForName(CheckerNameRef CheckerName, StringRef name,
StringRef category);
virtual BugReport *
class BugType {
private:
- const CheckName Check;
- const std::string Name;
+ const CheckerNameRef CheckerName;
+ const std::string Description;
const std::string Category;
const CheckerBase *Checker;
bool SuppressOnSink;
virtual void anchor();
public:
- BugType(CheckName Check, StringRef Name, StringRef Cat,
- bool SuppressOnSink=false)
- : Check(Check), Name(Name), Category(Cat), Checker(nullptr),
- SuppressOnSink(SuppressOnSink) {}
+ BugType(CheckerNameRef CheckerName, StringRef Name, StringRef Cat,
+ bool SuppressOnSink = false)
+ : CheckerName(CheckerName), Description(Name), Category(Cat),
+ Checker(nullptr), SuppressOnSink(SuppressOnSink) {}
BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat,
- bool SuppressOnSink=false)
- : Check(Checker->getCheckName()), Name(Name), Category(Cat),
- Checker(Checker), SuppressOnSink(SuppressOnSink) {}
+ bool SuppressOnSink = false)
+ : CheckerName(Checker->getCheckerName()), Description(Name),
+ Category(Cat), Checker(Checker), SuppressOnSink(SuppressOnSink) {}
virtual ~BugType() = default;
- StringRef getName() const { return Name; }
+ StringRef getDescription() const { return Description; }
StringRef getCategory() const { return Category; }
- StringRef getCheckName() const {
- // FIXME: This is a workaround to ensure that the correct check name is used
- // The check names are set after the constructors are run.
+ StringRef getCheckerName() const {
+ // FIXME: This is a workaround to ensure that the correct checerk name is
+ // used. The checker names are set after the constructors are run.
// In case the BugType object is initialized in the checker's ctor
- // the Check field will be empty. To circumvent this problem we use
+ // the CheckerName field will be empty. To circumvent this problem we use
// CheckerBase whenever it is possible.
- StringRef CheckName =
- Checker ? Checker->getCheckName().getName() : Check.getName();
- assert(!CheckName.empty() && "Check name is not set properly.");
- return CheckName;
+ StringRef Ret = Checker ? Checker->getCheckerName() : CheckerName;
+ assert(!Ret.empty() && "Checker name is not set properly.");
+ return Ret;
}
/// isSuppressOnSink - Returns true if bug reports associated with this bug
const std::string desc;
void anchor() override;
public:
- BuiltinBug(class CheckName check, const char *name, const char *description)
- : BugType(check, name, categories::LogicError), desc(description) {}
+ BuiltinBug(class CheckerNameRef checker, const char *name,
+ const char *description)
+ : BugType(checker, name, categories::LogicError), desc(description) {}
BuiltinBug(const CheckerBase *checker, const char *name,
const char *description)
} // end eval namespace
class CheckerBase : public ProgramPointTag {
- CheckName Name;
+ CheckerNameRef Name;
friend class ::clang::ento::CheckerManager;
public:
StringRef getTagDescription() const override;
- CheckName getCheckName() const;
+ CheckerNameRef getCheckerName() const;
/// See CheckerManager::runCheckersForPrintState.
virtual void printState(raw_ostream &Out, ProgramStateRef State,
PSK_EscapeOther
};
-// This wrapper is used to ensure that only StringRefs originating from the
-// CheckerRegistry are used as check names. We want to make sure all check
-// name strings have a lifetime that keeps them alive at least until the path
-// diagnostics have been processed.
-class CheckName {
+/// This wrapper is used to ensure that only StringRefs originating from the
+/// CheckerRegistry are used as check names. We want to make sure all checker
+/// name strings have a lifetime that keeps them alive at least until the path
+/// diagnostics have been processed, since they are expected to be constexpr
+/// string literals (most likely generated by TblGen).
+class CheckerNameRef {
friend class ::clang::ento::CheckerRegistry;
StringRef Name;
- explicit CheckName(StringRef Name) : Name(Name) {}
+ explicit CheckerNameRef(StringRef Name) : Name(Name) {}
public:
- CheckName() = default;
+ CheckerNameRef() = default;
StringRef getName() const { return Name; }
operator StringRef() const { return Name; }
ASTContext &Context;
const LangOptions LangOpts;
AnalyzerOptions &AOptions;
- CheckName CurrentCheckName;
+ CheckerNameRef CurrentCheckerName;
public:
CheckerManager(ASTContext &Context, AnalyzerOptions &AOptions)
~CheckerManager();
- void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
- CheckName getCurrentCheckName() const { return CurrentCheckName; }
+ void setCurrentCheckerName(CheckerNameRef name) { CurrentCheckerName = name; }
+ CheckerNameRef getCurrentCheckerName() const { return CurrentCheckerName; }
bool hasPathSensitiveCheckers() const;
assert(!ref && "Checker already registered, use getChecker!");
CHECKER *checker = new CHECKER(std::forward<AT>(Args)...);
- checker->Name = CurrentCheckName;
+ checker->Name = CurrentCheckerName;
CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
CHECKER::_register(checker, *this);
ref = checker;
const LocationContext *LCtx,
ProgramStateRef State);
- /// Evaluate a call, running pre- and post-call checks and allowing checkers
+ /// Evaluate a call, running pre- and post-call checkers and allowing checkers
/// to be responsible for handling the evaluation of the call itself.
void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
const CallEvent &Call);
PathDiagnostic::~PathDiagnostic() = default;
PathDiagnostic::PathDiagnostic(
- StringRef CheckName, const Decl *declWithIssue, StringRef bugtype,
+ StringRef CheckerName, const Decl *declWithIssue, StringRef bugtype,
StringRef verboseDesc, StringRef shortDesc, StringRef category,
PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique,
std::unique_ptr<FilesToLineNumsMap> ExecutedLines)
- : CheckName(CheckName), DeclWithIssue(declWithIssue),
+ : CheckerName(CheckerName), DeclWithIssue(declWithIssue),
BugType(StripTrailingDots(bugtype)),
VerboseDesc(StripTrailingDots(verboseDesc)),
ShortDesc(StripTrailingDots(shortDesc)),
BT.reset(new BugType(this, "call to main", "example analyzer plugin"));
auto report =
- std::make_unique<PathSensitiveBugReport>(*BT, BT->getName(), N);
+ std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
report->addRange(Callee->getSourceRange());
C.emitReport(std::move(report));
}
.Case("true", true)
.Case("false", false)
.Default(false);
- Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks);
+ Opts.DisableAllCheckers = Args.hasArg(OPT_analyzer_disable_all_checks);
Opts.visualizeExplodedGraphWithGraphViz =
Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
DefaultBool CheckCStringBufferOverlap;
DefaultBool CheckCStringNotNullTerm;
- CheckName CheckNameCStringNullArg;
- CheckName CheckNameCStringOutOfBounds;
- CheckName CheckNameCStringBufferOverlap;
- CheckName CheckNameCStringNotNullTerm;
+ CheckerNameRef CheckNameCStringNullArg;
+ CheckerNameRef CheckNameCStringOutOfBounds;
+ CheckerNameRef CheckNameCStringBufferOverlap;
+ CheckerNameRef CheckNameCStringNotNullTerm;
};
CStringChecksFilter Filter;
void ento::register##name(CheckerManager &mgr) { \
CStringChecker *checker = mgr.getChecker<CStringChecker>(); \
checker->Filter.Check##name = true; \
- checker->Filter.CheckName##name = mgr.getCurrentCheckName(); \
+ checker->Filter.CheckName##name = mgr.getCurrentCheckerName(); \
} \
\
- bool ento::shouldRegister##name(const LangOptions &LO) { \
- return true; \
- }
+ bool ento::shouldRegister##name(const LangOptions &LO) { return true; }
- REGISTER_CHECKER(CStringNullArg)
- REGISTER_CHECKER(CStringOutOfBounds)
- REGISTER_CHECKER(CStringBufferOverlap)
+REGISTER_CHECKER(CStringNullArg)
+REGISTER_CHECKER(CStringOutOfBounds)
+REGISTER_CHECKER(CStringBufferOverlap)
REGISTER_CHECKER(CStringNotNullTerm)
public:
DefaultBool Check_CallAndMessageUnInitRefArg;
- CheckName CheckName_CallAndMessageUnInitRefArg;
+ CheckerNameRef CheckName_CallAndMessageUnInitRefArg;
void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
if (!N)
return;
- auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getName(), N);
+ auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
if (BadE) {
R->addRange(BadE->getSourceRange());
if (BadE->isGLValue())
}
assert(BT && "Unknown message kind.");
- auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getName(), N);
+ auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
const ObjCMessageExpr *ME = msg.getOriginExpr();
R->addRange(ME->getReceiverRange());
void ento::registerCallAndMessageUnInitRefArg(CheckerManager &mgr) {
CallAndMessageChecker *Checker = mgr.getChecker<CallAndMessageChecker>();
Checker->Check_CallAndMessageUnInitRefArg = true;
- Checker->CheckName_CallAndMessageUnInitRefArg = mgr.getCurrentCheckName();
+ Checker->CheckName_CallAndMessageUnInitRefArg = mgr.getCurrentCheckerName();
}
bool ento::shouldRegisterCallAndMessageUnInitRefArg(const LangOptions &LO) {
DefaultBool check_FloatLoopCounter;
DefaultBool check_UncheckedReturn;
- CheckName checkName_bcmp;
- CheckName checkName_bcopy;
- CheckName checkName_bzero;
- CheckName checkName_gets;
- CheckName checkName_getpw;
- CheckName checkName_mktemp;
- CheckName checkName_mkstemp;
- CheckName checkName_strcpy;
- CheckName checkName_DeprecatedOrUnsafeBufferHandling;
- CheckName checkName_rand;
- CheckName checkName_vfork;
- CheckName checkName_FloatLoopCounter;
- CheckName checkName_UncheckedReturn;
+ CheckerNameRef checkName_bcmp;
+ CheckerNameRef checkName_bcopy;
+ CheckerNameRef checkName_bzero;
+ CheckerNameRef checkName_gets;
+ CheckerNameRef checkName_getpw;
+ CheckerNameRef checkName_mktemp;
+ CheckerNameRef checkName_mkstemp;
+ CheckerNameRef checkName_strcpy;
+ CheckerNameRef checkName_DeprecatedOrUnsafeBufferHandling;
+ CheckerNameRef checkName_rand;
+ CheckerNameRef checkName_vfork;
+ CheckerNameRef checkName_FloatLoopCounter;
+ CheckerNameRef checkName_UncheckedReturn;
};
class WalkAST : public StmtVisitor<WalkAST> {
#define REGISTER_CHECKER(name) \
void ento::register##name(CheckerManager &mgr) { \
- SecuritySyntaxChecker *checker = mgr.getChecker<SecuritySyntaxChecker>(); \
+ SecuritySyntaxChecker *checker = mgr.getChecker<SecuritySyntaxChecker>(); \
checker->filter.check_##name = true; \
- checker->filter.checkName_##name = mgr.getCurrentCheckName(); \
+ checker->filter.checkName_##name = mgr.getCurrentCheckerName(); \
} \
\
- bool ento::shouldRegister##name(const LangOptions &LO) { \
- return true; \
- }
+ bool ento::shouldRegister##name(const LangOptions &LO) { return true; }
REGISTER_CHECKER(bcmp)
REGISTER_CHECKER(bcopy)
"Logic error"));
ExplodedNode *N = C.generateNonFatalErrorNode();
- auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getName(), N);
+ auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
// Mark region of problematic base class for later use in the BugVisitor.
R->markInteresting(BaseClassRegion);
const SourceManager &SM = C.getSourceManager();
FullSourceLoc FL(CE->getArg(0)->getBeginLoc(), SM);
std::string HashContent =
- GetIssueString(SM, FL, getCheckName().getName(), "Category",
+ GetIssueString(SM, FL, getCheckerName().getName(), "Category",
C.getLocationContext()->getDecl(), Opts);
reportBug(HashContent, C);
};
DefaultBool ChecksEnabled[CK_NumCheckKinds];
- CheckName CheckNames[CK_NumCheckKinds];
+ CheckerNameRef CheckNames[CK_NumCheckKinds];
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
auto *checker = Mgr.getChecker<IteratorChecker>(); \
checker->ChecksEnabled[IteratorChecker::CK_##name] = true; \
checker->CheckNames[IteratorChecker::CK_##name] = \
- Mgr.getCurrentCheckName(); \
+ Mgr.getCurrentCheckerName(); \
} \
\
- bool ento::shouldRegister##name(const LangOptions &LO) { \
- return true; \
- }
+ bool ento::shouldRegister##name(const LangOptions &LO) { return true; }
REGISTER_CHECKER(IteratorRangeChecker)
REGISTER_CHECKER(MismatchedIteratorChecker)
/// Check that all ivars are invalidated.
DefaultBool check_InstanceVariableInvalidation;
- CheckName checkName_MissingInvalidationMethod;
- CheckName checkName_InstanceVariableInvalidation;
+ CheckerNameRef checkName_MissingInvalidationMethod;
+ CheckerNameRef checkName_InstanceVariableInvalidation;
};
class IvarInvalidationCheckerImpl {
const ObjCIvarDecl *IvarDecl,
const IvarToPropMapTy &IvarToPopertyMap);
- void reportNoInvalidationMethod(CheckName CheckName,
+ void reportNoInvalidationMethod(CheckerNameRef CheckName,
const ObjCIvarDecl *FirstIvarDecl,
const IvarToPropMapTy &IvarToPopertyMap,
const ObjCInterfaceDecl *InterfaceD,
}
void IvarInvalidationCheckerImpl::reportNoInvalidationMethod(
- CheckName CheckName, const ObjCIvarDecl *FirstIvarDecl,
+ CheckerNameRef CheckName, const ObjCIvarDecl *FirstIvarDecl,
const IvarToPropMapTy &IvarToPopertyMap,
const ObjCInterfaceDecl *InterfaceD, bool MissingDeclaration) const {
SmallString<128> sbuf;
IvarInvalidationChecker *checker = \
mgr.getChecker<IvarInvalidationChecker>(); \
checker->Filter.check_##name = true; \
- checker->Filter.checkName_##name = mgr.getCurrentCheckName(); \
+ checker->Filter.checkName_##name = mgr.getCurrentCheckerName(); \
} \
\
- bool ento::shouldRegister##name(const LangOptions &LO) { \
- return true; \
- }
+ bool ento::shouldRegister##name(const LangOptions &LO) { return true; }
REGISTER_CHECKER(InstanceVariableInvalidation)
REGISTER_CHECKER(MissingInvalidationMethod)
DefaultBool IsOptimistic;
DefaultBool ChecksEnabled[CK_NumCheckKinds];
- CheckName CheckNames[CK_NumCheckKinds];
+ CheckerNameRef CheckNames[CK_NumCheckKinds];
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
MallocChecker *checker = mgr.getChecker<MallocChecker>();
checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true;
checker->CheckNames[MallocChecker::CK_InnerPointerChecker] =
- mgr.getCurrentCheckName();
+ mgr.getCurrentCheckerName();
}
void ento::registerDynamicMemoryModeling(CheckerManager &mgr) {
void ento::register##name(CheckerManager &mgr) { \
MallocChecker *checker = mgr.getChecker<MallocChecker>(); \
checker->ChecksEnabled[MallocChecker::CK_##name] = true; \
- checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
+ checker->CheckNames[MallocChecker::CK_##name] = \
+ mgr.getCurrentCheckerName(); \
} \
\
- bool ento::shouldRegister##name(const LangOptions &LO) { \
- return true; \
- }
+ bool ento::shouldRegister##name(const LangOptions &LO) { return true; }
REGISTER_CHECKER(MallocChecker)
REGISTER_CHECKER(NewDeleteChecker)
DefaultBool CheckNullablePassedToNonnull;
DefaultBool CheckNullableReturnedFromNonnull;
- CheckName CheckNameNullPassedToNonnull;
- CheckName CheckNameNullReturnedFromNonnull;
- CheckName CheckNameNullableDereferenced;
- CheckName CheckNameNullablePassedToNonnull;
- CheckName CheckNameNullableReturnedFromNonnull;
+ CheckerNameRef CheckNameNullPassedToNonnull;
+ CheckerNameRef CheckNameNullReturnedFromNonnull;
+ CheckerNameRef CheckNameNullableDereferenced;
+ CheckerNameRef CheckNameNullablePassedToNonnull;
+ CheckerNameRef CheckNameNullableReturnedFromNonnull;
};
NullabilityChecksFilter Filter;
void ento::register##name##Checker(CheckerManager &mgr) { \
NullabilityChecker *checker = mgr.getChecker<NullabilityChecker>(); \
checker->Filter.Check##name = true; \
- checker->Filter.CheckName##name = mgr.getCurrentCheckName(); \
+ checker->Filter.CheckName##name = mgr.getCurrentCheckerName(); \
checker->NeedTracking = checker->NeedTracking || trackingRequired; \
checker->NoDiagnoseCallsToSystemHeaders = \
checker->NoDiagnoseCallsToSystemHeaders || \
mgr.getAnalyzerOptions().getCheckerBooleanOption( \
- checker, "NoDiagnoseCallsToSystemHeaders", true); \
+ checker, "NoDiagnoseCallsToSystemHeaders", true); \
} \
\
bool ento::shouldRegister##name##Checker(const LangOptions &LO) { \
BT.reset(new BuiltinBug(this, "Array subscript is undefined"));
// Generate a report for this bug.
- auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getName(), N);
+ auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
R->addRange(A->getIdx()->getSourceRange());
bugreporter::trackExpressionValue(N, A->getIdx(), *R);
C.emitReport(std::move(R));
};
DefaultBool ChecksEnabled[CK_NumCheckKinds];
- CheckName CheckNames[CK_NumCheckKinds];
+ CheckerNameRef CheckNames[CK_NumCheckKinds];
void checkPreStmt(const VAArgExpr *VAA, CheckerContext &C) const;
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
void ento::register##name##Checker(CheckerManager &mgr) { \
ValistChecker *checker = mgr.getChecker<ValistChecker>(); \
checker->ChecksEnabled[ValistChecker::CK_##name] = true; \
- checker->CheckNames[ValistChecker::CK_##name] = mgr.getCurrentCheckName(); \
+ checker->CheckNames[ValistChecker::CK_##name] = \
+ mgr.getCurrentCheckerName(); \
} \
\
bool ento::shouldRegister##name##Checker(const LangOptions &LO) { \
void ento::registerPureVirtualCallChecker(CheckerManager &Mgr) {
auto *Chk = Mgr.getChecker<VirtualCallChecker>();
- Chk->BT_Pure = std::make_unique<BugType>(
- Mgr.getCurrentCheckName(), "Pure virtual method call",
- categories::CXXObjectLifecycle);
+ Chk->BT_Pure = std::make_unique<BugType>(Mgr.getCurrentCheckerName(),
+ "Pure virtual method call",
+ categories::CXXObjectLifecycle);
}
void ento::registerVirtualCallChecker(CheckerManager &Mgr) {
auto *Chk = Mgr.getChecker<VirtualCallChecker>();
if (!Mgr.getAnalyzerOptions().getCheckerBooleanOption(
- Mgr.getCurrentCheckName(), "PureOnly")) {
+ Mgr.getCurrentCheckerName(), "PureOnly")) {
Chk->BT_Impure = std::make_unique<BugType>(
- Mgr.getCurrentCheckName(), "Unexpected loss of virtual dispatch",
+ Mgr.getCurrentCheckerName(), "Unexpected loss of virtual dispatch",
categories::CXXObjectLifecycle);
Chk->ShowFixIts = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
- Mgr.getCurrentCheckName(), "ShowFixIts");
+ Mgr.getCurrentCheckerName(), "ShowFixIts");
}
}
generateDiagnosticForBasicReport(const BasicBugReport *R) {
const BugType &BT = R->getBugType();
return std::make_unique<PathDiagnostic>(
- BT.getCheckName(), R->getDeclWithIssue(), BT.getName(),
+ BT.getCheckerName(), R->getDeclWithIssue(), BT.getDescription(),
R->getDescription(), R->getShortDescription(/*UseFallback=*/false),
BT.getCategory(), R->getUniqueingLocation(), R->getUniqueingDecl(),
std::make_unique<FilesToLineNumsMap>());
const SourceManager &SM) {
const BugType &BT = R->getBugType();
return std::make_unique<PathDiagnostic>(
- BT.getCheckName(), R->getDeclWithIssue(), BT.getName(),
+ BT.getCheckerName(), R->getDeclWithIssue(), BT.getDescription(),
R->getDescription(), R->getShortDescription(/*UseFallback=*/false),
BT.getCategory(), R->getUniqueingLocation(), R->getUniqueingDecl(),
findExecutedLines(SM, R->getErrorNode()));
PathDiagnosticLocation Loc,
ArrayRef<SourceRange> Ranges,
ArrayRef<FixItHint> Fixits) {
- EmitBasicReport(DeclWithIssue, Checker->getCheckName(), Name, Category, Str,
+ EmitBasicReport(DeclWithIssue, Checker->getCheckerName(), Name, Category, Str,
Loc, Ranges, Fixits);
}
void BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
- CheckName CheckName,
+ CheckerNameRef CheckName,
StringRef name, StringRef category,
StringRef str, PathDiagnosticLocation Loc,
ArrayRef<SourceRange> Ranges,
emitReport(std::move(R));
}
-BugType *BugReporter::getBugTypeForName(CheckName CheckName, StringRef name,
- StringRef category) {
+BugType *BugReporter::getBugTypeForName(CheckerNameRef CheckName,
+ StringRef name, StringRef category) {
SmallString<136> fullDesc;
llvm::raw_svector_ostream(fullDesc) << CheckName.getName() << ":" << name
<< ":" << category;
int ImplicitNullDerefEvent::Tag;
StringRef CheckerBase::getTagDescription() const {
- return getCheckName().getName();
+ return getCheckerName().getName();
}
-CheckName CheckerBase::getCheckName() const { return Name; }
+CheckerNameRef CheckerBase::getCheckerName() const { return Name; }
CheckerProgramPointTag::CheckerProgramPointTag(StringRef CheckerName,
StringRef Msg)
CheckerProgramPointTag::CheckerProgramPointTag(const CheckerBase *Checker,
StringRef Msg)
- : SimpleProgramPointTag(Checker->getCheckName().getName(), Msg) {}
+ : SimpleProgramPointTag(Checker->getCheckerName().getName(), Msg) {}
raw_ostream& clang::ento::operator<<(raw_ostream &Out,
const CheckerBase &Checker) {
- Out << Checker.getCheckName().getName();
+ Out << Checker.getCheckerName().getName();
return Out;
}
continue;
Indent(Out, Space, IsDot)
- << "{ \"checker\": \"" << CT.second->getCheckName().getName()
+ << "{ \"checker\": \"" << CT.second->getCheckerName().getName()
<< "\", \"messages\": [" << NL;
Indent(Out, InnerSpace, IsDot)
<< '\"' << TempBuf.str().trim() << '\"' << NL;
if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
// Invalidate placement args.
// FIXME: Once we figure out how we want allocators to work,
- // we should be using the usual pre-/(default-)eval-/post-call checks here.
+ // we should be using the usual pre-/(default-)eval-/post-call checkers
+ // here.
State = Call->invalidateRegions(blockCount);
if (!State)
return;
os << "\n<!-- FUNCTIONNAME " << declName << " -->\n";
os << "\n<!-- ISSUEHASHCONTENTOFLINEINCONTEXT "
- << GetIssueHash(SMgr, L, D.getCheckName(), D.getBugType(), DeclWithIssue,
- PP.getLangOpts()) << " -->\n";
+ << GetIssueHash(SMgr, L, D.getCheckerName(), D.getBugType(),
+ DeclWithIssue, PP.getLangOpts())
+ << " -->\n";
os << "\n<!-- BUGLINE "
<< LineNumber
o << " <key>type</key>";
EmitString(o, D->getBugType()) << '\n';
o << " <key>check_name</key>";
- EmitString(o, D->getCheckName()) << '\n';
+ EmitString(o, D->getCheckerName()) << '\n';
o << " <!-- This hash is experimental and going to change! -->\n";
o << " <key>issue_hash_content_of_line_in_context</key>";
: D->getLocation().asLocation()),
SM);
const Decl *DeclWithIssue = D->getDeclWithIssue();
- EmitString(o, GetIssueHash(SM, L, D->getCheckName(), D->getBugType(),
+ EmitString(o, GetIssueHash(SM, L, D->getCheckerName(), D->getBugType(),
DeclWithIssue, LangOpts))
<< '\n';
const PathPieces &Path = Diag.path.flatten(false);
const SourceManager &SMgr = Path.front()->getLocation().getManager();
- auto Iter = RuleMapping.find(Diag.getCheckName());
+ auto Iter = RuleMapping.find(Diag.getCheckerName());
assert(Iter != RuleMapping.end() && "Rule ID is not in the array index map?");
return json::Object{
*Diag.getLocation().asLocation().getExpansionLoc().getFileEntry(),
SMgr, Artifacts))}},
{"ruleIndex", Iter->getValue()},
- {"ruleId", Diag.getCheckName()}};
+ {"ruleId", Diag.getCheckerName()}};
}
static StringRef getRuleDescription(StringRef CheckName) {
}
static json::Object createRule(const PathDiagnostic &Diag) {
- StringRef CheckName = Diag.getCheckName();
+ StringRef CheckName = Diag.getCheckerName();
json::Object Ret{
{"fullDescription", createMessage(getRuleDescription(CheckName))},
{"name", CheckName},
llvm::StringSet<> Seen;
llvm::for_each(Diags, [&](const PathDiagnostic *D) {
- StringRef RuleID = D->getCheckName();
+ StringRef RuleID = D->getCheckerName();
std::pair<llvm::StringSet<>::iterator, bool> P = Seen.insert(RuleID);
if (P.second) {
RuleMapping[RuleID] = Rules.size(); // Maps RuleID to an Array Index.
if (isBisonFile(C)) {
reportAnalyzerProgress("Skipping bison-generated file\n");
- } else if (Opts->DisableAllChecks) {
+ } else if (Opts->DisableAllCheckers) {
// Don't analyze if the user explicitly asked for no checks to be performed
// on this file.
// Initialize the CheckerManager with all enabled checkers.
for (const auto *Checker : enabledCheckers) {
- CheckerMgr.setCurrentCheckName(CheckName(Checker->FullName));
+ CheckerMgr.setCurrentCheckerName(CheckerNameRef(Checker->FullName));
Checker->Initialize(CheckerMgr);
}
}
void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
FilesMade *filesMade) override {
for (const auto *PD : Diags)
- Output << PD->getCheckName() << ":" << PD->getShortDescription();
+ Output << PD->getCheckerName() << ":" << PD->getShortDescription();
}
StringRef getName() const override { return "Test"; }