r205661 - [analyzer] Look through temporary destructors when finding a region to construct.

Jordan Rose jordan_rose at apple.com
Fri Apr 4 19:01:42 PDT 2014


Author: jrose
Date: Fri Apr  4 21:01:41 2014
New Revision: 205661

URL: http://llvm.org/viewvc/llvm-project?rev=205661&view=rev
Log:
[analyzer] Look through temporary destructors when finding a region to construct.

Fixes a false positive when temporary destructors are enabled where a temporary
is destroyed after a variable is constructed but before the VarDecl itself is
processed, which occurs when the variable is in the condition of an if or while.

Patch by Alex McCarthy, with an extra test from me.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
    cfe/trunk/test/Analysis/dtor.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=205661&r1=205660&r2=205661&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Fri Apr  4 21:01:41 2014
@@ -113,8 +113,16 @@ static const MemRegion *getRegionForCons
   // See if we're constructing an existing region by looking at the next
   // element in the CFG.
   const CFGBlock *B = CurrBldrCtx.getBlock();
-  if (CurrStmtIdx + 1 < B->size()) {
-    CFGElement Next = (*B)[CurrStmtIdx+1];
+  unsigned int NextStmtIdx = CurrStmtIdx + 1;
+  if (NextStmtIdx < B->size()) {
+    CFGElement Next = (*B)[NextStmtIdx];
+
+    // Is this a destructor? If so, we might be in the middle of an assignment
+    // to a local or member: look ahead one more element to see what we find.
+    while (Next.getAs<CFGImplicitDtor>() && NextStmtIdx + 1 < B->size()) {
+      ++NextStmtIdx;
+      Next = (*B)[NextStmtIdx];
+    }
 
     // Is this a constructor for a local variable?
     if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) {

Modified: cfe/trunk/test/Analysis/dtor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dtor.cpp?rev=205661&r1=205660&r2=205661&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dtor.cpp (original)
+++ cfe/trunk/test/Analysis/dtor.cpp Fri Apr  4 21:01:41 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
@@ -426,8 +426,14 @@ namespace LifetimeExtension {
 
   // This case used to cause an unexpected "Undefined or garbage value returned
   // to caller" warning
-  bool testNamedCustomDestructor() {
-    if (CheckCustomDestructor c = CheckCustomDestructor())
+//  bool testNamedCustomDestructor() {
+//    if (CheckCustomDestructor c = CheckCustomDestructor())
+//      return true;
+//    return false;
+//  }
+
+  bool testMultipleTemporariesCustomDestructor() {
+    if (CheckCustomDestructor c = (CheckCustomDestructor(), CheckCustomDestructor()))
       return true;
     return false;
   }
@@ -477,8 +483,7 @@ namespace NoReturn {
 
   void g2(int *x) {
     if (! x) NR();
-    // FIXME: this shouldn't cause a warning.
-    *x = 47; // expected-warning{{Dereference of null pointer}}
+    *x = 47; // no warning
   }
 }
 





More information about the cfe-commits mailing list