]> granicus.if.org Git - clang/commitdiff
Added transfer function logic for ReturnStmts.
authorTed Kremenek <kremenek@apple.com>
Thu, 7 Feb 2008 01:08:27 +0000 (01:08 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 7 Feb 2008 01:08:27 +0000 (01:08 +0000)
Fixed insidious bug in handling dereferences.

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

Analysis/GRConstants.cpp
Analysis/RValues.cpp
Analysis/RValues.h
Analysis/ValueState.cpp

index 516af280f438fb641d190192cbc8f9d9f81fc9fd..65cb6e76e8c3fa01a86122e1c67920c8d8132e37 100644 (file)
@@ -256,6 +256,8 @@ public:
   /// VisitBinaryOperator - Transfer function logic for binary operators.
   void VisitBinaryOperator(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst);
   
+  void VisitAssignmentLHS(Expr* E, NodeTy* Pred, NodeSet& Dst);
+  
   /// VisitDeclStmt - Transfer function logic for DeclStmts.
   void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst); 
   
@@ -671,7 +673,7 @@ void GRConstants::VisitUnaryOperator(UnaryOperator* U,
       }
         
       case UnaryOperator::Deref: {
-        const LValue& L1 = GetLValue(St, U->getSubExpr());
+        const LValue& L1 = cast<LValue>(GetValue(St, U->getSubExpr()));
         Nodify(Dst, U, N1, SetValue(St, U, GetValue(St, L1)));
         break;
       }
@@ -682,11 +684,31 @@ void GRConstants::VisitUnaryOperator(UnaryOperator* U,
   }
 }
 
+void GRConstants::VisitAssignmentLHS(Expr* E, GRConstants::NodeTy* Pred,
+                                     GRConstants::NodeSet& Dst) {
+
+  if (isa<DeclRefExpr>(E))
+    return;
+  
+  if (UnaryOperator* U = dyn_cast<UnaryOperator>(E)) {
+    if (U->getOpcode() == UnaryOperator::Deref) {
+      Visit(U->getSubExpr(), Pred, Dst);
+      return;
+    }
+  }
+  
+  Visit(E, Pred, Dst);
+}
+
 void GRConstants::VisitBinaryOperator(BinaryOperator* B,
                                       GRConstants::NodeTy* Pred,
                                       GRConstants::NodeSet& Dst) {
   NodeSet S1;
-  Visit(B->getLHS(), Pred, S1);
+  
+  if (B->isAssignmentOp())
+    VisitAssignmentLHS(B->getLHS(), Pred, S1);
+  else
+    Visit(B->getLHS(), Pred, S1);
 
   for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
     NodeTy* N1 = *I1;
@@ -712,6 +734,11 @@ void GRConstants::VisitBinaryOperator(BinaryOperator* B,
       
       if (Op <= BinaryOperator::Or) {
         
+        if (isa<InvalidValue>(V1) || isa<UninitializedValue>(V1)) {
+          Nodify(Dst, B, N2, SetValue(St, B, V1));
+          continue;
+        }
+        
         if (isa<LValue>(V1)) {
           // FIXME: Add support for RHS being a non-lvalue.
           const LValue& L1 = cast<LValue>(V1);
@@ -824,6 +851,14 @@ void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred,
       break;
     }
       
+    case Stmt::ReturnStmtClass:
+      if (Expr* R = cast<ReturnStmt>(S)->getRetValue())
+        Visit(R, Pred, Dst);
+      else
+        Dst.Add(Pred);
+      
+      break;
+      
     case Stmt::DeclStmtClass:
       VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
       break;
index bf6a0afdfd336769b74634eb19505eb83b6a2c9d..bfdfe3bf45be65466c8350e38412900a0d41605b 100644 (file)
@@ -481,7 +481,9 @@ RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
     return nonlval::SymbolVal(SymMgr.getSymbol(D));
 }
 
-
+void RValue::print() const {
+  print(*llvm::cerr.stream());
+}
 
 //===----------------------------------------------------------------------===//
 // Pretty-Printing.
index 01df7dcd4823f5892a6e44cd9f7c6a55b55ad18f..19ebbd4b4cf46fb2a32841e40adc17be0f4e89dd 100644 (file)
@@ -260,7 +260,7 @@ public:
   inline bool isInvalid() const { return getRawKind() == InvalidKind; }
   
   void print(std::ostream& OS) const;
-  void print() const { print(*llvm::cerr.stream()); }
+  void print() const;
   
   // Implement isa<T> support.
   static inline bool classof(const RValue*) { return true; }
@@ -323,7 +323,7 @@ protected:
   NonLValue NE(ValueManager& ValMgr, const LValue& RHS) const;
   
 public:
-  void print(std::ostream& Out) const;
+//  void print(std::ostream& Out) const;
 
   RValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
                             const LValue& RHS) const;
index 00b6607536b59500a4869ee453e91938535296e0..1b08d8ea3996b59ce436ca6fbb17dcfd08ea4843 100644 (file)
@@ -155,6 +155,10 @@ LValue ValueStateManager::GetLValue(const StateTy& St, Stmt* S) {
   if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
     return lval::DeclVal(DR->getDecl());
   
+  if (UnaryOperator* U = dyn_cast<UnaryOperator>(S))
+    if (U->getOpcode() == UnaryOperator::Deref)
+      return cast<LValue>(GetValue(St, U->getSubExpr()));
+  
   return cast<LValue>(GetValue(St, S));
 }