Fix crash when using --analyzer-store=region when handling initializers with nested arrays/structs whose values are not explicitly specified. Fixes <rdar://problem/7403269>.

llvm-svn: 89384
This commit is contained in:
Ted Kremenek 2009-11-19 20:20:24 +00:00
parent 0c54d2da14
commit 439a6d146c
2 changed files with 78 additions and 11 deletions

View File

@ -215,6 +215,13 @@ public:
/// getDefaultBinding - Returns an SVal* representing an optional default
/// binding associated with a region and its subregions.
Optional<SVal> getDefaultBinding(RegionBindings B, const MemRegion *R);
/// setImplicitDefaultValue - Set the default binding for the provided
/// MemRegion to the value implicitly defined for compound literals when
/// the value is not specified.
const GRState *setImplicitDefaultValue(const GRState *state,
const MemRegion *R,
QualType T);
/// getLValueString - Returns an SVal representing the lvalue of a
/// StringLiteral. Within RegionStore a StringLiteral has an
@ -1437,6 +1444,30 @@ RegionStoreManager::BindCompoundLiteral(const GRState *state,
return Bind(state, loc::MemRegionVal(R), V);
}
const GRState *RegionStoreManager::setImplicitDefaultValue(const GRState *state,
const MemRegion *R,
QualType T) {
Store store = state->getStore();
RegionBindings B = GetRegionBindings(store);
SVal V;
if (Loc::IsLocType(T))
V = ValMgr.makeNull();
else if (T->isIntegerType())
V = ValMgr.makeZeroVal(T);
else if (T->isStructureType() || T->isArrayType()) {
// Set the default value to a zero constant when it is a structure
// or array. The type doesn't really matter.
V = ValMgr.makeZeroVal(ValMgr.getContext().IntTy);
}
else {
return state;
}
B = RBFactory.Add(B, R, BindingVal(V, BindingVal::Default));
return state->makeWithStore(B.getRoot());
}
const GRState *RegionStoreManager::BindArray(const GRState *state,
const TypedRegion* R,
SVal Init) {
@ -1478,6 +1509,10 @@ const GRState *RegionStoreManager::BindArray(const GRState *state,
return CopyLazyBindings(*LCV, state, R);
// Remaining case: explicit compound values.
if (Init.isUnknown())
return setImplicitDefaultValue(state, R, ElementTy);
nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
uint64_t i = 0;
@ -1497,17 +1532,10 @@ const GRState *RegionStoreManager::BindArray(const GRState *state,
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 (ElementTy->isIntegerType()) {
SVal V = ValMgr.makeZeroVal(ElementTy);
Store store = state->getStore();
RegionBindings B = GetRegionBindings(store);
B = RBFactory.Add(B, R, BindingVal(V, BindingVal::Default));
state = state->makeWithStore(B.getRoot());
}
}
// If the init list is shorter than the array length, set the
// array default value.
if (i < size)
state = setImplicitDefaultValue(state, R, ElementTy);
return state;
}

View File

@ -470,3 +470,42 @@ int pr3135() {
return 0;
}
//===----------------------------------------------------------------------===//
// <rdar://problem/7403269> - Test that we handle compound initializers with
// partially unspecified array values. Previously this caused a crash.
//===----------------------------------------------------------------------===//
typedef struct RDar7403269 {
unsigned x[10];
unsigned y;
} RDar7403269;
void rdar7403269() {
RDar7403269 z = { .y = 0 };
if (z.x[4] == 0)
return;
int *p = 0;
*p = 0xDEADBEEF; // no-warning
}
typedef struct RDar7403269_b {
struct zorg { int w; int k; } x[10];
unsigned y;
} RDar7403269_b;
void rdar7403269_b() {
RDar7403269_b z = { .y = 0 };
if (z.x[5].w == 0)
return;
int *p = 0;
*p = 0xDEADBEEF; // no-warning
}
void rdar7403269_b_pos() {
RDar7403269_b z = { .y = 0 };
if (z.x[5].w == 1)
return;
int *p = 0;
*p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
}