aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/RegionStore.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-01-26 23:51:00 +0000
committerTed Kremenek <kremenek@apple.com>2010-01-26 23:51:00 +0000
commitfee90811c665893bc27a9bfa8b116548afe1b89b (patch)
treedcbc675091e8bf4227fea5a345ee209dc6d0cfbb /lib/Checker/RegionStore.cpp
parent97053091c0e4df12ffb662b284b6ab329ca1c40f (diff)
Teach RegionStore to handle initialization of incomplete arrays in structures using a compound value. Fixes <rdar://problem/7515938>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94622 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/RegionStore.cpp')
-rw-r--r--lib/Checker/RegionStore.cpp29
1 files changed, 18 insertions, 11 deletions
diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp
index 39686c22df..7fb9c0fd1b 100644
--- a/lib/Checker/RegionStore.cpp
+++ b/lib/Checker/RegionStore.cpp
@@ -1572,13 +1572,16 @@ const GRState *RegionStoreManager::setImplicitDefaultValue(const GRState *state,
const GRState *RegionStoreManager::BindArray(const GRState *state,
const TypedRegion* R,
SVal Init) {
-
- QualType T = R->getValueType(getContext());
- ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
- QualType ElementTy = CAT->getElementType();
-
- uint64_t size = CAT->getSize().getZExtValue();
-
+
+ ASTContext &Ctx = getContext();
+ const ArrayType *AT =
+ cast<ArrayType>(Ctx.getCanonicalType(R->getValueType(Ctx)));
+ QualType ElementTy = AT->getElementType();
+ Optional<uint64_t> Size;
+
+ 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();
@@ -1590,6 +1593,11 @@ const GRState *RegionStoreManager::BindArray(const GRState *state,
// 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;
+
for (uint64_t i = 0; i < size; ++i, ++j) {
if (j >= len)
break;
@@ -1618,7 +1626,7 @@ const GRState *RegionStoreManager::BindArray(const GRState *state,
nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
uint64_t i = 0;
- for (; i < size; ++i, ++VI) {
+ for (; Size.hasValue() ? i < Size.getValue() : true ; ++i, ++VI) {
// The init list might be shorter than the array length.
if (VI == VE)
break;
@@ -1626,16 +1634,15 @@ const GRState *RegionStoreManager::BindArray(const GRState *state,
SVal Idx = ValMgr.makeArrayIndex(i);
const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, getContext());
- if (CAT->getElementType()->isStructureType())
+ if (ElementTy->isStructureType())
state = BindStruct(state, ER, *VI);
else
- // FIXME: Do we need special handling of nested arrays?
state = Bind(state, ValMgr.makeLoc(ER), *VI);
}
// If the init list is shorter than the array length, set the
// array default value.
- if (i < size)
+ if (Size.hasValue() && i < Size.getValue())
state = setImplicitDefaultValue(state, R, ElementTy);
return state;