]> granicus.if.org Git - clang/commitdiff
Revert "[analyzer] Create a temp region when a method is called on a struct rvalue."
authorJordan Rose <jordan_rose@apple.com>
Sat, 29 Sep 2012 01:36:47 +0000 (01:36 +0000)
committerJordan Rose <jordan_rose@apple.com>
Sat, 29 Sep 2012 01:36:47 +0000 (01:36 +0000)
This reverts commit 0006ba445962621ed82ec84400a6b978205a3fbc.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164876 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/ExprEngine.cpp
test/Analysis/array-struct-region.cpp

index 3965f048424acf8f16ad802f424b282498b4ab23..06216f83ea90241d55d749b9ea64faf3c288ce86 100644 (file)
@@ -1470,23 +1470,6 @@ void ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A,
   }
 }
 
-/// If the value of the given expression is a NonLoc, copy it into a new
-/// temporary region, and replace the value of the expression with that.
-static ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
-                                                     const LocationContext *LC,
-                                                     const Expr *E) {
-  SVal V = State->getSVal(E, LC);
-
-  if (isa<NonLoc>(V)) {
-    MemRegionManager &MRMgr = State->getStateManager().getRegionManager();
-    const MemRegion *R  = MRMgr.getCXXTempObjectRegion(E, LC);
-    State = State->bindLoc(loc::MemRegionVal(R), V);
-    State = State->BindExpr(E, LC, loc::MemRegionVal(R));
-  }
-
-  return State;
-}
-
 /// VisitMemberExpr - Transfer function for member expressions.
 void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
                                  ExplodedNodeSet &TopDst) {
@@ -1495,7 +1478,6 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
   ExplodedNodeSet Dst;
   Decl *member = M->getMemberDecl();
 
-  // Handle static member variables accessed via member syntax.
   if (VarDecl *VD = dyn_cast<VarDecl>(member)) {
     assert(M->isGLValue());
     Bldr.takeNodes(Pred);
@@ -1504,27 +1486,36 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
     return;
   }
 
-  ProgramStateRef state = Pred->getState();
-  const LocationContext *LCtx = Pred->getLocationContext();
-  Expr *BaseExpr = M->getBase()->IgnoreParens();
-
   // Handle C++ method calls.
   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(member)) {
-    if (MD->isInstance())
-      state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
-
+    Bldr.takeNodes(Pred);
     SVal MDVal = svalBuilder.getFunctionPointer(MD);
-    state = state->BindExpr(M, LCtx, MDVal);
-
+    ProgramStateRef state =
+      Pred->getState()->BindExpr(M, Pred->getLocationContext(), MDVal);
     Bldr.generateNode(M, Pred, state);
     return;
   }
 
-  // Handle regular struct fields / member variables.
-  state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
-  SVal baseExprVal = state->getSVal(BaseExpr, LCtx);
 
-  FieldDecl *field = cast<FieldDecl>(member);
+  FieldDecl *field = dyn_cast<FieldDecl>(member);
+  if (!field) // FIXME: skipping member expressions for non-fields
+    return;
+
+  Expr *baseExpr = M->getBase()->IgnoreParens();
+  ProgramStateRef state = Pred->getState();
+  const LocationContext *LCtx = Pred->getLocationContext();
+  SVal baseExprVal = state->getSVal(baseExpr, Pred->getLocationContext());
+
+  // If we're accessing a field of an rvalue, we need to treat it like a
+  // temporary object.
+  if (isa<NonLoc>(baseExprVal)) {
+    const MemRegion *R  =
+      svalBuilder.getRegionManager().getCXXTempObjectRegion(baseExpr, LCtx);
+    SVal L = loc::MemRegionVal(R);
+    state = state->bindLoc(L, baseExprVal);
+    baseExprVal = L;
+  }
+
   SVal L = state->getLValue(field, baseExprVal);
   if (M->isGLValue()) {
     ExplodedNodeSet Tmp;
index 22fbf2ff33b185682c8742037e1cecb4db802e0a..f610fbb2f8d2491291b1fd3d03743bb6b02d3057 100644 (file)
@@ -1,7 +1,5 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s
 // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s
 
 void clang_analyzer_eval(int);
 
@@ -13,14 +11,7 @@ struct S {
 #endif
 };
 
-#ifdef INLINE
-struct S getS() {
-  struct S s = { 42 };
-  return s;
-}
-#else
 struct S getS();
-#endif
 
 
 void testAssignment() {