diff options
-rw-r--r-- | include/clang/Analysis/PathSensitive/BugReporter.h | 31 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/Checker.h | 16 | ||||
-rw-r--r-- | lib/Analysis/BugReporter.cpp | 4 | ||||
-rw-r--r-- | lib/Analysis/BugReporterVisitors.cpp | 8 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 13 |
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); |