From 6f4160828db75f36b22a204da202723c592644f3 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Wed, 27 Feb 2013 18:49:57 +0000 Subject: [analyzer] Teach FindLastStoreBRVisitor to understand stores of the same value. Consider this case: int *p = 0; p = getPointerThatMayBeNull(); *p = 1; If we inline 'getPointerThatMayBeNull', we might know that the value of 'p' is NULL, and thus emit a null pointer dereference report. However, we usually want to suppress such warnings as error paths, and we do so by using FindLastStoreBRVisitor to see where the NULL came from. In this case, though, because 'p' was NULL both before and after the assignment, the visitor would decide that the "last store" was the initialization, not the re-assignment. This commit changes FindLastStoreBRVisitor to consider all PostStore nodes that assign to this region. This still won't catches changes made directly by checkers if they re-assign the same value, but it does handle the common case in user-written code and will trigger ReturnVisitor's suppression machinery as expected. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176201 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'lib/StaticAnalyzer/Core/BugReporterVisitors.cpp') diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 8dbfc8b61d..d712c18b78 100644 --- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -378,13 +378,20 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ, } } - // Otherwise, check that Succ has this binding and Pred does not, i.e. this is - // where the binding first occurred. + // Otherwise, see if this is the store site: + // (1) Succ has this binding and Pred does not, i.e. this is + // where the binding first occurred. + // (2) Succ has this binding and is a PostStore node for this region, i.e. + // the same binding was re-assigned here. if (!StoreSite) { if (Succ->getState()->getSVal(R) != V) return NULL; - if (Pred->getState()->getSVal(R) == V) - return NULL; + + if (Pred->getState()->getSVal(R) == V) { + Optional PS = Succ->getLocationAs(); + if (!PS || PS->getLocationValue() != R) + return NULL; + } StoreSite = Succ; -- cgit v1.2.3-70-g09d2