r179766 - [analyzer] Don't crash if we cache out after making a temporary region.

Jordan Rose jordan_rose at apple.com
Thu Apr 18 09:33:40 PDT 2013


Author: jrose
Date: Thu Apr 18 11:33:40 2013
New Revision: 179766

URL: http://llvm.org/viewvc/llvm-project?rev=179766&view=rev
Log:
[analyzer] Don't crash if we cache out after making a temporary region.

A C++ overloaded operator may be implemented as an instance method, and
that instance method may be called on an rvalue object, which has no
associated region. The analyzer handles this by creating a temporary region
just for the evaluation of this call; however, it is possible that /by
creating the region/, the analyzer ends up in a previously-explored state.
In this case we don't need to continue along this path.

This doesn't actually show any behavioral change now, but it starts being
used with the next commit and prevents an assertion failure there.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/test/Analysis/operator-calls.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=179766&r1=179765&r2=179766&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Thu Apr 18 11:33:40 2013
@@ -864,9 +864,13 @@ void ExprEngine::Visit(const Stmt *S, Ex
           const LocationContext *LCtx = Pred->getLocationContext();
           ProgramStateRef NewState =
             createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
-          if (NewState != State)
+          if (NewState != State) {
             Pred = Bldr.generateNode(OCE, Pred, NewState, /*Tag=*/0,
                                      ProgramPoint::PreStmtKind);
+            // Did we cache out?
+            if (!Pred)
+              break;
+          }
         }
       }
       // FALLTHROUGH

Modified: cfe/trunk/test/Analysis/operator-calls.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/operator-calls.cpp?rev=179766&r1=179765&r2=179766&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/operator-calls.cpp (original)
+++ cfe/trunk/test/Analysis/operator-calls.cpp Thu Apr 18 11:33:40 2013
@@ -49,3 +49,39 @@ namespace UserDefinedConversions {
     clang_analyzer_eval(obj); // expected-warning{{TRUE}}
   }
 }
+
+
+namespace RValues {
+  struct SmallOpaque {
+    float x;
+    int operator +() const {
+      return (int)x;
+    }
+  };
+
+  struct LargeOpaque {
+    float x[4];
+    int operator +() const {
+      return (int)x[0];
+    }
+  };
+
+  SmallOpaque getSmallOpaque() {
+    SmallOpaque obj;
+    obj.x = 1.0;
+    return obj;
+  }
+
+  LargeOpaque getLargeOpaque() {
+    LargeOpaque obj = LargeOpaque();
+    obj.x[0] = 1.0;
+    return obj;
+  }
+
+  void test(int coin) {
+    // Force a cache-out when we try to conjure a temporary region for the operator call.
+    // ...then, don't crash.
+    clang_analyzer_eval(+(coin ? getSmallOpaque() : getSmallOpaque())); // expected-warning{{UNKNOWN}}
+    clang_analyzer_eval(+(coin ? getLargeOpaque() : getLargeOpaque())); // expected-warning{{UNKNOWN}}
+  }
+}





More information about the cfe-commits mailing list