aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Analysis/PathSensitive/BugReporter.h31
-rw-r--r--include/clang/Analysis/PathSensitive/Checker.h16
-rw-r--r--lib/Analysis/BugReporter.cpp4
-rw-r--r--lib/Analysis/BugReporterVisitors.cpp8
-rw-r--r--lib/Analysis/GRExprEngineInternalChecks.cpp13
5 files changed, 60 insertions, 12 deletions
diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h
index 70eb1da8f2..b99eaee953 100644
--- a/include/clang/Analysis/PathSensitive/BugReporter.h
+++ b/include/clang/Analysis/PathSensitive/BugReporter.h
@@ -244,6 +244,35 @@ public:
}
};
+class EnhancedBugReport : public RangedBugReport {
+public:
+ typedef void (*VisitorCreator)(BugReporterContext &BRcC, const void *data,
+ const ExplodedNode *N);
+
+private:
+ typedef std::vector<std::pair<VisitorCreator, const void*> > Creators;
+ Creators creators;
+
+public:
+ EnhancedBugReport(BugType& D, const char* description, ExplodedNode *n)
+ : RangedBugReport(D, description, n) {}
+
+ EnhancedBugReport(BugType& D, const char *shortDescription,
+ const char *description, ExplodedNode *n)
+ : RangedBugReport(D, shortDescription, description, n) {}
+
+ ~EnhancedBugReport() {}
+
+ void registerInitialVisitors(BugReporterContext& BRC, const ExplodedNode* N) {
+ for (Creators::iterator I = creators.begin(), E = creators.end(); I!=E; ++I)
+ I->first(BRC, I->second, N);
+ }
+
+ void addVisitorCreator(VisitorCreator creator, const void *data) {
+ creators.push_back(std::make_pair(creator, data));
+ }
+};
+
//===----------------------------------------------------------------------===//
// BugReporter and friends.
//===----------------------------------------------------------------------===//
@@ -471,7 +500,7 @@ const Stmt *GetDenomExpr(const ExplodedNode *N);
const Stmt *GetCalleeExpr(const ExplodedNode *N);
const Stmt *GetRetValExpr(const ExplodedNode *N);
-void registerTrackNullOrUndefValue(BugReporterContext& BRC, const Stmt *S,
+void registerTrackNullOrUndefValue(BugReporterContext& BRC, const void *stmt,
const ExplodedNode* N);
} // end namespace clang::bugreporter
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h
index 278f85c160..77373699a2 100644
--- a/include/clang/Analysis/PathSensitive/Checker.h
+++ b/include/clang/Analysis/PathSensitive/Checker.h
@@ -17,6 +17,7 @@
#include "clang/Analysis/Support/SaveAndRestore.h"
#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
#include "clang/Analysis/PathSensitive/GRState.h"
+#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/StmtCXX.h"
@@ -67,9 +68,18 @@ public:
ExplodedNode *&getPredecessor() { return Pred; }
const GRState *getState() { return B.GetState(Pred); }
- ExplodedNode *generateNode(const Stmt* S,
- const GRState *state) {
- return B.generateNode(S, state, Pred);
+ ASTContext &getASTContext() {
+ return Eng.getContext();
+ }
+
+ ExplodedNode *generateNode(const Stmt* S, const GRState *state,
+ bool markAsSink = false) {
+ ExplodedNode *node = B.generateNode(S, state, Pred);
+
+ if (markAsSink && node)
+ node->markAsSink();
+
+ return node;
}
void addTransition(ExplodedNode *node) {
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp
index af4fd384e8..354bafd989 100644
--- a/lib/Analysis/BugReporter.cpp
+++ b/lib/Analysis/BugReporter.cpp
@@ -41,8 +41,8 @@ BugReporterContext::~BugReporterContext() {
//===----------------------------------------------------------------------===//
static inline const Stmt* GetStmt(ProgramPoint P) {
- if (const PostStmt* PS = dyn_cast<PostStmt>(&P))
- return PS->getStmt();
+ if (const StmtPoint* SP = dyn_cast<StmtPoint>(&P))
+ return SP->getStmt();
else if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P))
return BE->getSrc()->getTerminator();
diff --git a/lib/Analysis/BugReporterVisitors.cpp b/lib/Analysis/BugReporterVisitors.cpp
index 77501bbba2..604542b2c1 100644
--- a/lib/Analysis/BugReporterVisitors.cpp
+++ b/lib/Analysis/BugReporterVisitors.cpp
@@ -189,6 +189,10 @@ public:
else if (V.isUndef()) {
os << "Uninitialized value stored to ";
}
+ else if (isa<nonloc::ConcreteInt>(V)) {
+ os << "The value " << cast<nonloc::ConcreteInt>(V).getValue()
+ << " is assigned to ";
+ }
else
return NULL;
@@ -296,9 +300,11 @@ static void registerTrackConstraint(BugReporterContext& BRC, SVal Constraint,
}
void clang::bugreporter::registerTrackNullOrUndefValue(BugReporterContext& BRC,
- const Stmt *S,
+ const void *data,
const ExplodedNode* N) {
+ const Stmt *S = static_cast<const Stmt*>(data);
+
if (!S)
return;
diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp
index 3c316eb3e9..d22f276a55 100644
--- a/lib/Analysis/GRExprEngineInternalChecks.cpp
+++ b/lib/Analysis/GRExprEngineInternalChecks.cpp
@@ -583,7 +583,7 @@ public:
if (stateNull && !stateNotNull) {
// Generate an error node. Check for a null node in case
// we cache out.
- if (ExplodedNode *errorNode = C.generateNode(CE, stateNull)) {
+ if (ExplodedNode *errorNode = C.generateNode(CE, stateNull, true)) {
// Lazily allocate the BugType object if it hasn't already been
// created. Ownership is transferred to the BugReporter object once
@@ -592,12 +592,15 @@ public:
BT = new BugType("Argument with 'nonnull' attribute passed null",
"API");
- RangedBugReport *R =
- new RangedBugReport(*BT, "Null pointer passed as an argument to a "
- "'nonnull' parameter", errorNode);
+ EnhancedBugReport *R =
+ new EnhancedBugReport(*BT,
+ "Null pointer passed as an argument to a "
+ "'nonnull' parameter", errorNode);
// Highlight the range of the argument that was null.
- R->addRange((*I)->getSourceRange());
+ const Expr *arg = *I;
+ R->addRange(arg->getSourceRange());
+ R->addVisitorCreator(registerTrackNullOrUndefValue, arg);
// Emit the bug report.
C.EmitReport(R);