]> granicus.if.org Git - clang/commitdiff
Fix PR5316: make assignment expressions can be visited as lvalue. Then we
authorZhongxing Xu <xuzhongxing@gmail.com>
Fri, 30 Oct 2009 07:19:39 +0000 (07:19 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Fri, 30 Oct 2009 07:19:39 +0000 (07:19 +0000)
can get the correct base lvalue.
Revert r85578.

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

include/clang/Analysis/PathSensitive/GRExprEngine.h
lib/Analysis/GRExprEngine.cpp

index e30b4271f1dbc72ded026509379eff11cd3a527f..89ca337f15e793b2d9893fc2232f950b06c91fca 100644 (file)
@@ -433,7 +433,8 @@ protected:
                                 ExplodedNode* Pred, ExplodedNodeSet& Dst);
 
   /// VisitBinaryOperator - Transfer function logic for binary operators.
-  void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+  void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred, 
+                           ExplodedNodeSet& Dst, bool asLValue);
 
 
   /// VisitCall - Transfer function for function calls.
index 99e214400ecf9d61cffbd8604ae54bdcac6a3db3..88e67981ac1e40bfaa3f32a66936160a92254fb9 100644 (file)
@@ -388,11 +388,11 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
 
       if (AMgr.shouldEagerlyAssume() && (B->isRelationalOp() || B->isEqualityOp())) {
         ExplodedNodeSet Tmp;
-        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
+        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp, false);
         EvalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
       }
       else
-        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
+        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
 
       break;
     }
@@ -414,7 +414,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
     }
 
     case Stmt::CompoundAssignOperatorClass:
-      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
+      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
       break;
 
     case Stmt::CompoundLiteralExprClass:
@@ -582,6 +582,11 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
       return;
     }
 
+    case Stmt::BinaryOperatorClass:
+    case Stmt::CompoundAssignOperatorClass:
+      VisitBinaryOperator(cast<BinaryOperator>(Ex), Pred, Dst, true);
+      return;
+
     default:
       // Arbitrary subexpressions can return aggregate temporaries that
       // can be used in a lvalue context.  We need to enhance our support
@@ -1092,26 +1097,12 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred,
     // FIXME: Should we insert some assumption logic in here to determine
     // if "Base" is a valid piece of memory?  Before we put this assumption
     // later when using FieldOffset lvals (which we no longer have).
-    SVal BaseV = state->getSVal(Base);
-    
-    if (nonloc::LazyCompoundVal *LVC=dyn_cast<nonloc::LazyCompoundVal>(&BaseV)){
-      const LazyCompoundValData *D = LVC->getCVData();
-      const FieldRegion * FR =
-        getStateManager().getRegionManager().getFieldRegion(Field,
-                                                            D->getRegion());
-
-      SVal V = D->getState()->getSVal(loc::MemRegionVal(FR));
-      MakeNode(Dst, M, *I, state->BindExpr(M, V));
-    }
-    else {
-      SVal L = state->getLValue(Field, BaseV);
+    SVal L = state->getLValue(Field, state->getSVal(Base));
 
-      if (asLValue)
-        MakeNode(Dst, M, *I, state->BindExpr(M, L),
-                 ProgramPoint::PostLValueKind);
-      else
-        EvalLoad(Dst, M, *I, state, L);
-    }
+    if (asLValue)
+      MakeNode(Dst, M, *I, state->BindExpr(M, L), ProgramPoint::PostLValueKind);
+    else
+      EvalLoad(Dst, M, *I, state, L);
   }
 }
 
@@ -2686,7 +2677,7 @@ void GRExprEngine::VisitReturnStmt(ReturnStmt* S, ExplodedNode* Pred,
 
 void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
                                        ExplodedNode* Pred,
-                                       ExplodedNodeSet& Dst) {
+                                       ExplodedNodeSet& Dst, bool asLValue) {
 
   ExplodedNodeSet Tmp1;
   Expr* LHS = B->getLHS()->IgnoreParens();
@@ -2732,10 +2723,16 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
           unsigned Count = Builder->getCurrentBlockCount();
           RightV = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), Count);
         }
-        
+
+        SVal ExprVal;
+        if (asLValue)
+          ExprVal = LeftV;
+        else
+          ExprVal = RightV;
+
         // Simulate the effects of a "store":  bind the value of the RHS
         // to the L-Value represented by the LHS.
-        EvalStore(Dst, B, LHS, *I2, state->BindExpr(B, RightV), LeftV, RightV);
+        EvalStore(Dst, B, LHS, *I2, state->BindExpr(B, ExprVal), LeftV, RightV);
         continue;
       }