aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Analysis/PathDiagnostic.h8
-rw-r--r--include/clang/Analysis/PathSensitive/BugReporter.h24
-rw-r--r--lib/Analysis/BugReporter.cpp18
-rw-r--r--lib/Analysis/CFRefCount.cpp14
-rw-r--r--lib/Analysis/CheckDeadStores.cpp6
-rw-r--r--lib/Analysis/GRExprEngineInternalChecks.cpp2
-rw-r--r--lib/Driver/HTMLDiagnostics.cpp9
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);