[cfe-commits] r109734 - in /cfe/trunk: lib/Checker/RegionStore.cpp test/Analysis/array-struct.c

Jordy Rose jediknil at belkadan.com
Wed Jul 28 23:40:33 PDT 2010


Author: jrose
Date: Thu Jul 29 01:40:33 2010
New Revision: 109734

URL: http://llvm.org/viewvc/llvm-project?rev=109734&view=rev
Log:
Use a LazyCompoundVal to handle initialization with a string literal, rather than copying each character.

Modified:
    cfe/trunk/lib/Checker/RegionStore.cpp
    cfe/trunk/test/Analysis/array-struct.c

Modified: cfe/trunk/lib/Checker/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/RegionStore.cpp?rev=109734&r1=109733&r2=109734&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/RegionStore.cpp (original)
+++ cfe/trunk/lib/Checker/RegionStore.cpp Thu Jul 29 01:40:33 2010
@@ -1131,13 +1131,11 @@
     if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) {
       int64_t i = CI->getValue().getSExtValue();
       int64_t byteLength = Str->getByteLength();
-      if (i > byteLength) {
-        // Buffer overflow checking in GRExprEngine should handle this case,
-        // but we shouldn't rely on it to not overflow here if that checking
-        // is disabled.
-        return UnknownVal();
-      }
-      char c = (i == byteLength) ? '\0' : Str->getStrData()[i];
+      // Technically, only i == byteLength is guaranteed to be null.
+      // However, such overflows should be caught before reaching this point;
+      // the only time such an access would be made is if a string literal was
+      // used to initialize a larger array.
+      char c = (i >= byteLength) ? '\0' : Str->getStrData()[i];
       return ValMgr.makeIntVal(c, T);
     }
   }
@@ -1475,35 +1473,14 @@
   if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(AT))
     Size = CAT->getSize().getZExtValue();
 
-  // 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;
-
-    // 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.
-
-    // We assume that string constants are bound to
-    // constant arrays.
-    uint64_t size = Size.getValue();
-
-    for (uint64_t i = 0; i < size; ++i, ++j) {
-      if (j >= len)
-        break;
-
-      SVal Idx = ValMgr.makeArrayIndex(i);
-      const ElementRegion* ER = MRMgr.getElementRegion(ElementTy, Idx, R,
-                                                       getContext());
-
-      SVal V = ValMgr.makeIntVal(str[j], sizeof(char)*8, true);
-      store = Bind(store, loc::MemRegionVal(ER), V);
-    }
-
-    return store;
+  // Check if the init expr is a string literal.
+  if (loc::MemRegionVal *MRV = dyn_cast<loc::MemRegionVal>(&Init)) {
+    const StringRegion *S = cast<StringRegion>(MRV->getRegion());
+
+    // Treat the string as a lazy compound value.
+    nonloc::LazyCompoundVal LCV =
+      cast<nonloc::LazyCompoundVal>(ValMgr.makeLazyCompoundVal(store, S));
+    return CopyLazyBindings(LCV, store, R);
   }
 
   // Handle lazy compound values.

Modified: cfe/trunk/test/Analysis/array-struct.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/array-struct.c?rev=109734&r1=109733&r2=109734&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/array-struct.c (original)
+++ cfe/trunk/test/Analysis/array-struct.c Thu Jul 29 01:40:33 2010
@@ -178,3 +178,26 @@
   if (*q) { // no-warning
   }
 }
+
+int f19() {
+  char a[] = "abc";
+  char b[2] = "abc"; // expected-warning{{too long}}
+  char c[5] = "abc";
+
+  if (a[1] != 'b')
+    return 5; // expected-warning{{never executed}}
+  if (b[1] != 'b')
+    return 5; // expected-warning{{never executed}}
+  if (c[1] != 'b')
+    return 5; // expected-warning{{never executed}}
+
+  if (a[3] != 0)
+    return 5; // expected-warning{{never executed}}
+  if (c[3] != 0)
+    return 5; // expected-warning{{never executed}}
+
+  if (c[4] != 0)
+    return 5; // expected-warning{{never executed}}
+
+  return 0;
+}





More information about the cfe-commits mailing list