diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-08-18 01:05:30 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-08-18 01:05:30 +0000 |
commit | 592362b46ad69db0db0988e7f9d8cbe647510bdd (patch) | |
tree | 1fbb430abdc2851351450fffa683ff986e371f81 /lib | |
parent | 88232aadbe3e9b6dde2a9b0d7c91e677305de06a (diff) |
Enhance static analyzer diagnostics by introducing a new 'EnhancedBugReporter'
which allows custom checks to register callback creator functions for creating
BugReporterVisitor objects. This allows various checks to include diagnostics
such as 'assuming value is null' with little extra work. Eventually this API
should be refactored to be cleaner and more simple.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79302 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/BugReporter.cpp | 4 | ||||
-rw-r--r-- | lib/Analysis/BugReporterVisitors.cpp | 8 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 13 |
3 files changed, 17 insertions, 8 deletions
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); |