From 027e2667315f265a85c6241f26e8a514db219b3f Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 19 Nov 2009 20:20:24 +0000 Subject: [PATCH] Fix crash when using --analyzer-store=region when handling initializers with nested arrays/structs whose values are not explicitly specified. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89384 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/RegionStore.cpp | 50 ++++++++++++++++++++++------ test/Analysis/misc-ps-region-store.m | 39 ++++++++++++++++++++++ 2 files changed, 78 insertions(+), 11 deletions(-) diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index ae3fa14c2a..af2e359a00 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -215,6 +215,13 @@ public: /// getDefaultBinding - Returns an SVal* representing an optional default /// binding associated with a region and its subregions. Optional 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(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; } diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index 7ebc4a9fe5..23199b6361 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -470,3 +470,42 @@ int pr3135() { return 0; } +//===----------------------------------------------------------------------===// +// - 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}} +} + -- 2.40.0