Index: clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -19,6 +19,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Lex/Preprocessor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" @@ -135,7 +136,7 @@ SmallVector Fixits; BugReport(Kind kind, const BugType &bt, StringRef desc) - : K(kind), BT(bt), Description(desc) {} + : BugReport(kind, bt, "", desc) {} BugReport(Kind K, const BugType &BT, StringRef ShortDescription, StringRef Description) @@ -369,16 +370,13 @@ public: PathSensitiveBugReport(const BugType &bt, StringRef desc, const ExplodedNode *errorNode) - : BugReport(Kind::PathSensitive, bt, desc), ErrorNode(errorNode), - ErrorNodeRange(getStmt() ? getStmt()->getSourceRange() - : SourceRange()) {} + : PathSensitiveBugReport(bt, desc, desc, errorNode) {} PathSensitiveBugReport(const BugType &bt, StringRef shortDesc, StringRef desc, const ExplodedNode *errorNode) - : BugReport(Kind::PathSensitive, bt, shortDesc, desc), - ErrorNode(errorNode), - ErrorNodeRange(getStmt() ? getStmt()->getSourceRange() - : SourceRange()) {} + : PathSensitiveBugReport(bt, shortDesc, desc, errorNode, + /*LocationToUnique*/ {}, + /*DeclToUnique*/ nullptr) {} /// Create a PathSensitiveBugReport with a custom uniqueing location. /// @@ -391,11 +389,13 @@ const ExplodedNode *errorNode, PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique) - : BugReport(Kind::PathSensitive, bt, desc), ErrorNode(errorNode), - ErrorNodeRange(getStmt() ? getStmt()->getSourceRange() : SourceRange()), - UniqueingLocation(LocationToUnique), UniqueingDecl(DeclToUnique) { - assert(errorNode); - } + : PathSensitiveBugReport(bt, desc, desc, errorNode, LocationToUnique, + DeclToUnique) {} + + PathSensitiveBugReport(const BugType &bt, StringRef shortDesc, StringRef desc, + const ExplodedNode *errorNode, + PathDiagnosticLocation LocationToUnique, + const Decl *DeclToUnique); static bool classof(const BugReport *R) { return R->getKind() == Kind::PathSensitive; Index: clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h =================================================================== --- clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -302,28 +302,29 @@ /// For example, it'll return the checkers for the core package, if /// \p CmdLineArg is "core". CheckerInfoListRange getMutableCheckersForCmdLineArg(StringRef CmdLineArg); - - CheckerInfoList Checkers; - PackageInfoList Packages; /// Used for couting how many checkers belong to a certain package in the /// \c Checkers field. For convenience purposes. llvm::StringMap PackageSizes; + void resolveCheckerAndPackageOptions(); + void resolveDependencies(); + + DiagnosticsEngine &Diags; + AnalyzerOptions &AnOpts; + +public: + CheckerInfoList Checkers; + PackageInfoList Packages; + /// Contains all (Dependendent checker, Dependency) pairs. We need this, as /// we'll resolve dependencies after all checkers were added first. llvm::SmallVector, 0> Dependencies; - void resolveDependencies(); /// Contains all (FullName, CmdLineOption) pairs. Similarly to dependencies, /// we only modify the actual CheckerInfo and PackageInfo objects once all /// of them have been added. llvm::SmallVector, 0> PackageOptions; llvm::SmallVector, 0> CheckerOptions; - - void resolveCheckerAndPackageOptions(); - - DiagnosticsEngine &Diags; - AnalyzerOptions &AnOpts; CheckerInfoSet EnabledCheckers; }; Index: clang/lib/StaticAnalyzer/Core/BugReporter.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -40,6 +40,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" +#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" @@ -2106,6 +2107,34 @@ // Methods for BugReport and subclasses. //===----------------------------------------------------------------------===// +static bool isDependency(const CheckerRegistry &Registry, + StringRef CheckerName) { + for (const std::pair &Pair : Registry.Dependencies) { + if (Pair.second == CheckerName) + return true; + } + return false; +} + +PathSensitiveBugReport::PathSensitiveBugReport( + const BugType &bt, StringRef shortDesc, StringRef desc, + const ExplodedNode *errorNode, PathDiagnosticLocation LocationToUnique, + const Decl *DeclToUnique) + : BugReport(Kind::PathSensitive, bt, shortDesc, desc), ErrorNode(errorNode), + ErrorNodeRange(getStmt() ? getStmt()->getSourceRange() : SourceRange()), + UniqueingLocation(LocationToUnique), UniqueingDecl(DeclToUnique) { + + const CheckerRegistry &Registry = ErrorNode->getState() + ->getAnalysisManager() + .getCheckerManager() + ->getCheckerRegistry(); + + assert(!isDependency(Registry, bt.getCheckerName()) && + "Some checkers depend on this one! We don't allow dependency " + "checkers to emit warnings, because checkers should depend on " + "*modeling*, not *diagnostics*."); +} + void PathSensitiveBugReport::addVisitor( std::unique_ptr visitor) { if (!visitor) @@ -2194,12 +2223,12 @@ return; case bugreporter::TrackingKind::Condition: return; - } + } - llvm_unreachable( - "BugReport::markInteresting currently can only handle 2 different " - "tracking kinds! Please define what tracking kind should this entitiy" - "have, if it was already marked as interesting with a different kind!"); + llvm_unreachable( + "BugReport::markInteresting currently can only handle 2 different " + "tracking kinds! Please define what tracking kind should this entitiy" + "have, if it was already marked as interesting with a different kind!"); } void PathSensitiveBugReport::markInteresting(SymbolRef sym,