]> granicus.if.org Git - clang/commitdiff
Add placeholder code in the static analyzer for MemberExprs involving struct temporaries.
authorTed Kremenek <kremenek@apple.com>
Wed, 30 Apr 2008 22:17:15 +0000 (22:17 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 30 Apr 2008 22:17:15 +0000 (22:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50502 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/GRExprEngine.cpp

index 7bfcaab1121e5eee33e039b18773b952aedfd059..e10e9ae8f39ac9a8473a84ba8947e3382b6add9f 100644 (file)
@@ -831,22 +831,57 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred,
   // abstract address of the base object.
   NodeSet Tmp;
   
-  if (IsPointerType(Base->getType())) // Base always is an LVal.
-    Visit(Base, Pred, Tmp);
-  else  
-    VisitLVal(Base, Pred, Tmp);
+  if (asLVal) {
+      
+    if (IsPointerType(Base->getType())) // Base always is an LVal.
+      Visit(Base, Pred, Tmp);
+    else  
+      VisitLVal(Base, Pred, Tmp);
+  
+    for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+      ValueState* St = GetState(*I);
+      RVal BaseV = GetRVal(St, Base);      
+      
+      RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base),
+                                       M->getMemberDecl());
+      
+      MakeNode(Dst, M, *I, SetRVal(St, M, V));
+    }
+    
+    return;
+  }
+
+  // Evaluate the base.  Can be an LVal or NonLVal (depends on whether
+  //  or not isArrow() is true).
+  Visit(Base, Pred, Tmp);
   
   for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+
     ValueState* St = GetState(*I);
-    RVal BaseV = GetRVal(St, Base);      
+    RVal BaseV = GetRVal(St, Base);
     
-    RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base),
-                                     M->getMemberDecl());
+    if (IsPointerType(Base->getType())) {
+    
+      assert (M->isArrow());
+      
+      RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base),
+                                       M->getMemberDecl());
     
-    if (asLVal)
-      MakeNode(Dst, M, *I, SetRVal(St, M, V));
-    else
       EvalLoad(Dst, M, *I, St, V);
+    }
+    else {
+      
+      assert (!M->isArrow());
+      
+      if (BaseV.isUnknownOrUndef()) {
+        MakeNode(Dst, M, *I, SetRVal(St, M, BaseV));
+        continue;
+      }
+
+      // FIXME: Implement nonlval objects representing struct temporaries.
+      assert (isa<NonLVal>(BaseV));
+      MakeNode(Dst, M, *I, SetRVal(St, M, UnknownVal()));
+    }
   }
 }