]> granicus.if.org Git - clang/commitdiff
When a constant size array is casted to another type, its length should be scaled...
authorJordy Rose <jediknil@belkadan.com>
Fri, 25 Jun 2010 23:23:04 +0000 (23:23 +0000)
committerJordy Rose <jediknil@belkadan.com>
Fri, 25 Jun 2010 23:23:04 +0000 (23:23 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106911 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Checker/RegionStore.cpp
test/Analysis/no-outofbounds.c
test/Analysis/outofbound.c

index f7a0188a5319cde34666322eb26d93947f4b46fa..6b5e5e33f2d73d58cfba49b648b0e13f9521e663 100644 (file)
@@ -797,23 +797,28 @@ DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state,
 
     case MemRegion::VarRegionKind: {
       const VarRegion* VR = cast<VarRegion>(R);
+      ASTContext& Ctx = getContext();
       // Get the type of the variable.
-      QualType T = VR->getDesugaredValueType(getContext());
+      QualType T = VR->getDesugaredValueType(Ctx);
 
       // FIXME: Handle variable-length arrays.
       if (isa<VariableArrayType>(T))
         return UnknownVal();
 
+      CharUnits EleSize = Ctx.getTypeSizeInChars(EleTy);
+
       if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(T)) {
         // return the size as signed integer.
-        return ValMgr.makeIntVal(CAT->getSize(), false);
+        CharUnits RealEleSize = Ctx.getTypeSizeInChars(CAT->getElementType());
+        CharUnits::QuantityType EleRatio = RealEleSize / EleSize;
+        int64_t Length = CAT->getSize().getSExtValue();
+        return ValMgr.makeIntVal(Length * EleRatio, false);
       }
 
       // Clients can reinterpret ordinary variables as arrays, possibly of
       // another type. The width is rounded down to ensure that an access is
       // entirely within bounds.
-      CharUnits VarSize = getContext().getTypeSizeInChars(T);
-      CharUnits EleSize = getContext().getTypeSizeInChars(EleTy);
+      CharUnits VarSize = Ctx.getTypeSizeInChars(T);
       return ValMgr.makeIntVal(VarSize / EleSize, false);
     }
   }
index 771323b811143f226bf5b7356694ac19a543d3ab..49ee80e8c23bdf9ab9e9eebd2d01c569a042486f 100644 (file)
@@ -12,3 +12,9 @@ void f() {
   short *z = (short*) &x;
   short s = z[0] + z[1]; // no-warning
 }
+
+void g() {
+  int a[2];
+  char *b = (char*)a;
+  b[3] = 'c'; // no-warning
+}
index 2d09d8d76c2779b438e0a3736dd4fe09127ff622..24766be91837015a92a255f98e52847505a14cac 100644 (file)
@@ -43,3 +43,9 @@ void f5() {
   p[3] = '.'; // no-warning
   p[4] = '!'; // expected-warning{{out-of-bound}}
 }
+
+void f6() {
+  char a[2];
+  int *b = (int*)a;
+  b[1] = 3; // expected-warning{{out-of-bound}}
+}