diff options
-rw-r--r-- | include/clang/Analysis/PathDiagnostic.h | 8 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/BugReporter.h | 24 | ||||
-rw-r--r-- | lib/Analysis/BugReporter.cpp | 18 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 14 | ||||
-rw-r--r-- | lib/Analysis/CheckDeadStores.cpp | 6 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 2 | ||||
-rw-r--r-- | lib/Driver/HTMLDiagnostics.cpp | 9 |
7 files changed, 61 insertions, 20 deletions
diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Analysis/PathDiagnostic.h index bb31ee391f..e266ee8518 100644 --- a/include/clang/Analysis/PathDiagnostic.h +++ b/include/clang/Analysis/PathDiagnostic.h @@ -77,18 +77,22 @@ class PathDiagnostic { std::list<PathDiagnosticPiece*> path; unsigned Size; std::string Desc; + std::string Category; std::vector<std::string> OtherDesc; public: PathDiagnostic() : Size(0) {} - PathDiagnostic(const char* desc) : Size(0), Desc(desc) {} + PathDiagnostic(const char* desc, const char* category) + : Size(0), Desc(desc), Category(category) {} - PathDiagnostic(const std::string& desc) : Size(0), Desc(desc) {} + PathDiagnostic(const std::string& desc, const std::string& category) + : Size(0), Desc(desc), Category(category) {} ~PathDiagnostic(); const std::string& getDescription() const { return Desc; } + const std::string& getCategory() const { return Category; } typedef std::vector<std::string>::const_iterator meta_iterator; meta_iterator meta_begin() const { return OtherDesc.begin(); } diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h index 39e67f7798..7f2511f435 100644 --- a/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/include/clang/Analysis/PathSensitive/BugReporter.h @@ -45,6 +45,7 @@ public: virtual const char* getName() const = 0; virtual const char* getDescription() const { return getName(); } + virtual const char* getCategory() const { return ""; } virtual std::pair<const char**,const char**> getExtraDescriptiveText() { return std::pair<const char**, const char**>(0, 0); @@ -87,6 +88,10 @@ public: return getBugType().getDescription(); } + virtual const char* getCategory() const { + return getBugType().getCategory(); + } + virtual std::pair<const char**,const char**> getExtraDescriptiveText() { return getBugType().getExtraDescriptiveText(); } @@ -200,6 +205,11 @@ public: SourceLocation Loc, SourceRange* RangeBeg, unsigned NumRanges); + void EmitBasicReport(const char* BugName, const char* BugCategory, + const char* BugStr, SourceLocation Loc, + SourceRange* RangeBeg, unsigned NumRanges); + + void EmitBasicReport(const char* BugName, const char* BugStr, SourceLocation Loc) { EmitBasicReport(BugName, BugStr, Loc, 0, 0); @@ -210,6 +220,11 @@ public: EmitBasicReport(BugName, BugStr, Loc, &R, 1); } + void EmitBasicReport(const char* BugName, const char* Category, + const char* BugStr, SourceLocation Loc, SourceRange R) { + EmitBasicReport(BugName, Category, BugStr, Loc, &R, 1); + } + static bool classof(const BugReporter* R) { return true; } }; @@ -315,13 +330,16 @@ public: class SimpleBugType : public BugTypeCacheLocation { const char* name; + const char* category; const char* desc; public: - SimpleBugType(const char* n) : name(n), desc(n) {} - SimpleBugType(const char* n, const char* d) : name(n), desc(d) {} + SimpleBugType(const char* n) : name(n), category(""), desc(0) {} + SimpleBugType(const char* n, const char* c, const char* d) + : name(n), category(c), desc(d) {} virtual const char* getName() const { return name; } - virtual const char* getDescription() const { return desc; } + virtual const char* getDescription() const { return desc ? desc : name; } + virtual const char* getCategory() const { return category; } }; } // end clang namespace diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index b163eea1b8..6a1478a9cb 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -701,7 +701,8 @@ void BugReporter::EmitWarning(BugReport& R) { if (R.getBugType().isCached(R)) return; - llvm::OwningPtr<PathDiagnostic> D(new PathDiagnostic(R.getName())); + llvm::OwningPtr<PathDiagnostic> D(new PathDiagnostic(R.getName(), + R.getCategory())); GeneratePathDiagnostic(*D.get(), R); // Get the meta data. @@ -764,12 +765,17 @@ void BugReporter::EmitWarning(BugReport& R) { } } -void -BugReporter::EmitBasicReport(const char* name, const char* str, - SourceLocation Loc, - SourceRange* RBeg, unsigned NumRanges) { +void BugReporter::EmitBasicReport(const char* name, const char* str, + SourceLocation Loc, + SourceRange* RBeg, unsigned NumRanges) { + EmitBasicReport(name, "", str, Loc, RBeg, NumRanges); +} + +void BugReporter::EmitBasicReport(const char* name, const char* category, + const char* str, SourceLocation Loc, + SourceRange* RBeg, unsigned NumRanges) { - SimpleBugType BT(name); + SimpleBugType BT(name, category, 0); DiagCollector C(BT); Diagnostic& Diag = getDiagnostic(); Diag.Report(&C, getContext().getFullLoc(Loc), diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 25841cd8db..dcea4a6cc0 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -2020,6 +2020,10 @@ namespace { const CFRefCount& getTF() const { return TF; } virtual bool isLeak() const { return false; } + + const char* getCategory() const { + return "Memory (Core Foundation/Objective-C)"; + } }; class VISIBILITY_HIDDEN UseAfterRelease : public CFRefBug { @@ -2027,7 +2031,7 @@ namespace { UseAfterRelease(CFRefCount& tf) : CFRefBug(tf) {} virtual const char* getName() const { - return "Use-After-Release"; + return "use-after-release"; } virtual const char* getDescription() const { return "Reference-counted object is used after it is released."; @@ -2041,7 +2045,7 @@ namespace { BadRelease(CFRefCount& tf) : CFRefBug(tf) {} virtual const char* getName() const { - return "Bad Release"; + return "bad release"; } virtual const char* getDescription() const { return "Incorrect decrement of the reference count of a " @@ -2059,13 +2063,13 @@ namespace { virtual const char* getName() const { if (getTF().isGCEnabled()) - return "Memory Leak (GC)"; + return "Leak (GC)"; if (getTF().getLangOptions().getGCMode() == LangOptions::HybridGC) - return "Memory Leak (Hybrid MM, non-GC)"; + return "leak (hybrid MM, non-GC)"; assert (getTF().getLangOptions().getGCMode() == LangOptions::NonGC); - return "Memory Leak"; + return "leak"; } virtual const char* getDescription() const { diff --git a/lib/Analysis/CheckDeadStores.cpp b/lib/Analysis/CheckDeadStores.cpp index 73cb3f786b..d87bfb1964 100644 --- a/lib/Analysis/CheckDeadStores.cpp +++ b/lib/Analysis/CheckDeadStores.cpp @@ -59,19 +59,19 @@ public: case DeadIncrement: BugType = "dead increment"; case Standard: - if (!BugType) BugType = "dead store"; + if (!BugType) BugType = "dead assignment"; msg = "Value stored to '" + name + "' is never read"; break; case Enclosing: - BugType = "dead store"; + BugType = "dead nested assignment"; msg = "Although the value stored to '" + name + "' is used in the enclosing expression, the value is never actually" " read from '" + name + "'"; break; } - BR.EmitBasicReport(BugType, msg.c_str(), L, R); + BR.EmitBasicReport(BugType, "Dead Store", msg.c_str(), L, R); } void CheckVarDecl(VarDecl* VD, Expr* Ex, Expr* Val, diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp index 0c5f078e56..92c448cb2f 100644 --- a/lib/Analysis/GRExprEngineInternalChecks.cpp +++ b/lib/Analysis/GRExprEngineInternalChecks.cpp @@ -293,7 +293,7 @@ class VISIBILITY_HIDDEN CheckAttrNonNull : public GRSimpleAPICheck { public: CheckAttrNonNull() : - BT("'nonnull' argument passed null", + BT("'nonnull' argument passed null", "API", "Null pointer passed as an argument to a 'nonnull' parameter") {} virtual bool Audit(ExplodedNode<GRState>* N, GRStateManager& VMgr) { diff --git a/lib/Driver/HTMLDiagnostics.cpp b/lib/Driver/HTMLDiagnostics.cpp index 5025e87e59..22d3da9320 100644 --- a/lib/Driver/HTMLDiagnostics.cpp +++ b/lib/Driver/HTMLDiagnostics.cpp @@ -259,6 +259,15 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) { R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str()); } + const std::string& BugCategory = D.getCategory(); + + if (!BugCategory.empty()) { + std::string s; + llvm::raw_string_ostream os(s); + os << "\n<!-- BUGCATEGORY " << BugCategory << " -->\n"; + R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str()); + } + { std::string s; llvm::raw_string_ostream os(s); |