From: Jordy Rose Date: Fri, 25 Jun 2010 23:23:04 +0000 (+0000) Subject: When a constant size array is casted to another type, its length should be scaled... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4d912b24b393fe6b7422e5502f3a330cbdc5c6b7;p=clang When a constant size array is casted to another type, its length should be scaled as well. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106911 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp index f7a0188a53..6b5e5e33f2 100644 --- a/lib/Checker/RegionStore.cpp +++ b/lib/Checker/RegionStore.cpp @@ -797,23 +797,28 @@ DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state, case MemRegion::VarRegionKind: { const VarRegion* VR = cast(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(T)) return UnknownVal(); + CharUnits EleSize = Ctx.getTypeSizeInChars(EleTy); + if (const ConstantArrayType* CAT = dyn_cast(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); } } diff --git a/test/Analysis/no-outofbounds.c b/test/Analysis/no-outofbounds.c index 771323b811..49ee80e8c2 100644 --- a/test/Analysis/no-outofbounds.c +++ b/test/Analysis/no-outofbounds.c @@ -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 +} diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c index 2d09d8d76c..24766be918 100644 --- a/test/Analysis/outofbound.c +++ b/test/Analysis/outofbound.c @@ -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}} +}