]> granicus.if.org Git - clang/commitdiff
Add support for initializing array with string literal.
authorZhongxing Xu <xuzhongxing@gmail.com>
Sun, 30 Nov 2008 05:49:49 +0000 (05:49 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Sun, 30 Nov 2008 05:49:49 +0000 (05:49 +0000)
This fixes PR3127
http://llvm.org/bugs/show_bug.cgi?id=3127

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

lib/Analysis/GRExprEngine.cpp
lib/Analysis/RegionStore.cpp

index ee6b0202406b3c5715d5381443dde82088c4b007..5d4136de76d5b936691c8d064af03378275fb26a 100644 (file)
@@ -405,6 +405,10 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) {
       
       break;
     }
+
+    case Stmt::StringLiteralClass:
+      VisitLValue(cast<StringLiteral>(S), Pred, Dst);
+      break;
       
     case Stmt::UnaryOperatorClass:
       VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst, false);
index 1b62cc503232d913f119a372a3af1a69b8c0716e..92f4a6e71410174b4f6f2e6c769e9e7d6ae1cf9d 100644 (file)
@@ -637,17 +637,42 @@ Store RegionStoreManager::InitializeArray(Store store, const TypedRegion* R,
 
   ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
 
-  llvm::APInt Size = CAT->getSize();
+  llvm::APSInt Size(CAT->getSize(), false);
+
+  llvm::APSInt i = getBasicVals().getZeroWithPtrWidth(false);
+
+  // Check if the init expr is a StringLiteral.
+  if (isa<loc::MemRegionVal>(Init)) {
+    const MemRegion* InitR = cast<loc::MemRegionVal>(Init).getRegion();
+    const StringLiteral* S = cast<StringRegion>(InitR)->getStringLiteral();
+    const char* str = S->getStrData();
+    unsigned len = S->getByteLength();
+    unsigned j = 0;
+
+    for (; i < Size; ++i, ++j) {
+      SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
+      ElementRegion* ER = MRMgr.getElementRegion(Idx, R);
+
+      // Copy bytes from the string literal into the target array. Trailing
+      // bytes in the array that are not covered by the string literal are
+      // initialized to zero.
+      SVal V = (j < len) 
+        ? NonLoc::MakeVal(getBasicVals(), str[j], sizeof(char)*8, true)
+        : NonLoc::MakeVal(getBasicVals(), 0, sizeof(char)*8, true);
+
+      store = Bind(store, loc::MemRegionVal(ER), V);
+    }
+
+    return store;
+  }
 
-  llvm::APInt i = llvm::APInt::getNullValue(Size.getBitWidth());
 
   nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
 
   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
 
-  for (; i != Size; ++i) {
-    nonloc::ConcreteInt Idx(getBasicVals().getValue(llvm::APSInt(i, false)));
-
+  for (; i < Size; ++i) {
+    SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
     ElementRegion* ER = MRMgr.getElementRegion(Idx, R);
     
     store = Bind(store, loc::MemRegionVal(ER), (VI!=VE) ? *VI : UndefinedVal());