]> granicus.if.org Git - clang/commitdiff
Added lval type (and tracking) for StringLiterals.
authorTed Kremenek <kremenek@apple.com>
Tue, 22 Apr 2008 21:39:21 +0000 (21:39 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 22 Apr 2008 21:39:21 +0000 (21:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50109 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/RValues.h
lib/Analysis/CFRefCount.cpp
lib/Analysis/GRExprEngine.cpp
lib/Analysis/GRSimpleVals.cpp
lib/Analysis/RValues.cpp
lib/Analysis/ValueState.cpp
test/Analysis/null-deref-ps.c

index 45a5452ffcff2bee4c7b4f9f982ff727ae49b417..8a53588564a0e442d1bd142439f2bccdad345db0 100644 (file)
@@ -128,7 +128,7 @@ public:
   static NonLVal MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T);
   
   static NonLVal MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I);
-  
+    
   static NonLVal MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
     
   // Implement isa<T> support.
@@ -151,6 +151,8 @@ public:
     
   static LVal MakeVal(AddrLabelExpr* E);
   
+  static LVal MakeVal(StringLiteral* S);
+  
   // Implement isa<T> support.
   static inline bool classof(const RVal* V) {
     return V->getBaseKind() == LValKind;
@@ -274,7 +276,7 @@ public:
 namespace lval {
   
 enum Kind { SymbolValKind, GotoLabelKind, DeclValKind, FuncValKind,
-            ConcreteIntKind };
+            ConcreteIntKind, StringLiteralValKind };
 
 class SymbolVal : public LVal {
 public:
@@ -391,6 +393,24 @@ public:
   }
 };
   
+class StringLiteralVal : public LVal {
+public:
+  StringLiteralVal(StringLiteral* L) : LVal(StringLiteralValKind, L) {}
+  
+  StringLiteral* getLiteral() const { return (StringLiteral*) Data; }
+  
+  // Implement isa<T> support.
+  static inline bool classof(const RVal* V) {
+    return V->getBaseKind() == LValKind &&
+           V->getSubKind() == StringLiteralValKind;
+  }
+  
+  static inline bool classof(const LVal* V) {
+    return V->getSubKind() == StringLiteralValKind;
+  }
+};  
+    
+  
 } // end clang::lval namespace
 } // end clang namespace  
 
index 253e00589e04a8557075f8e3939286f37fd9ed65..499da2f85f273c5998a38d83c6f5a01444f9d7f3 100644 (file)
@@ -826,6 +826,8 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
       //  should compose behavior, not copy it.
       StateMgr.Unbind(StVals, cast<LVal>(V));
     }
+    else if (isa<nonlval::LValAsInteger>(V))
+      StateMgr.Unbind(StVals, cast<nonlval::LValAsInteger>(V).getLVal());
   }    
   
   St = StateMgr.getPersistentState(StVals);
index bdb742929de35be2760a14e5736c64b37145faa6..128ef82c63b05c301e1bbd50d1b62817f8e07194 100644 (file)
@@ -2014,6 +2014,7 @@ ValueState* GRExprEngine::AssumeAux(ValueState* St, LVal Cond,
     case lval::DeclValKind:
     case lval::FuncValKind:
     case lval::GotoLabelKind:
+    case lval::StringLiteralValKind:
       isFeasible = Assumption;
       return St;
 
index 2c14dde08bdaf7d68814e86b0cc50e777681dc16..e41df7662c212c9114d05102b348fa420cece0ab 100644 (file)
@@ -572,6 +572,10 @@ void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
     
     if (isa<LVal>(V))
       St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
+    else if (isa<nonlval::LValAsInteger>(V))
+      St = StateMgr.SetRVal(St, cast<nonlval::LValAsInteger>(V).getLVal(),
+                            UnknownVal());
+    
   }
   
   // Make up a symbol for the return value of this function.
index 86f5ac96fd889d4966da0529827b0ac6df5d746f..5e161f34a5c62a244bf7ec435f2420cfdb9f6e00 100644 (file)
@@ -240,6 +240,10 @@ RVal RVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
 
 LVal LVal::MakeVal(AddrLabelExpr* E) { return lval::GotoLabel(E->getLabel()); }
 
+LVal LVal::MakeVal(StringLiteral* S) {
+  return lval::StringLiteralVal(S);
+}
+
 //===----------------------------------------------------------------------===//
 // Utility methods for constructing RVals (both NonLVals and LVals).
 //===----------------------------------------------------------------------===//
@@ -392,6 +396,12 @@ void LVal::print(std::ostream& Out) const {
           << cast<lval::FuncVal>(this)->getDecl()->getIdentifier()->getName();
       break;
       
+    case lval::StringLiteralValKind:
+      Out << "literal \""
+          << cast<lval::StringLiteralVal>(this)->getLiteral()->getStrData()
+          << "\"";
+      break;
+      
     default:
       assert (false && "Pretty-printing not implemented for this LVal.");
       break;
index bba2e06a180bcabb6a8e4bb54def55226ed9fa36..8027ce9fcba1e30e816a030fc890064aa3cc2b1a 100644 (file)
@@ -264,6 +264,9 @@ RVal ValueStateManager::GetRVal(ValueState* St, Expr* E) {
       case Stmt::IntegerLiteralClass: {
         return NonLVal::MakeVal(BasicVals, cast<IntegerLiteral>(E));
       }
+        
+      case Stmt::StringLiteralClass:
+        return LVal::MakeVal(cast<StringLiteral>(E));
 
         // Casts where the source and target type are the same
         // are no-ops.  We blast through these to get the descendant
index 6d954fd957bf5bb00dbb24f2c9ef908c007b4fde..2e66e18b66a5a9d7991d82df63bdc5aab2742074 100644 (file)
@@ -38,4 +38,11 @@ int f4(int *p) {
     
   int *q = (int*) x;
   return *q; // expected-warning{{Dereference of null pointer.}}
-}
\ No newline at end of file
+}
+
+int f5() {
+  
+  char *s = "hello world";
+  return s[0]; // no-warning
+}
+