diff options
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 34 | ||||
-rw-r--r-- | test/Analysis/misc-ps.m | 7 |
2 files changed, 26 insertions, 15 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 4857a402cf..bc83d1636d 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -918,12 +918,13 @@ SVal RegionStoreManager::RetrieveElement(const GRState* state, const ElementRegion* R) { // Check if the region has a binding. RegionBindingsTy B = GetRegionBindings(state->getStore()); - const SVal* V = B.lookup(R); - if (V) + if (const SVal* V = B.lookup(R)) return *V; + const MemRegion* superR = R->getSuperRegion(); + // Check if the region is an element region of a string literal. - if (const StringRegion *StrR=dyn_cast<StringRegion>(R->getSuperRegion())) { + if (const StringRegion *StrR=dyn_cast<StringRegion>(superR)) { const StringLiteral *Str = StrR->getStringLiteral(); SVal Idx = R->getIndex(); if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) { @@ -937,12 +938,8 @@ SVal RegionStoreManager::RetrieveElement(const GRState* state, } } - const MemRegion* SuperR = R->getSuperRegion(); - // Check if the super region has a default value. - const SVal* D = state->get<RegionDefaultValue>(SuperR); - - if (D) { + if (const SVal *D = state->get<RegionDefaultValue>(superR)) { if (D->hasConjuredSymbol()) return ValMgr.getRegionValueSymbolVal(R); else @@ -950,14 +947,29 @@ SVal RegionStoreManager::RetrieveElement(const GRState* state, } // Check if the super region has a binding. - D = B.lookup(SuperR); - if (D) { + if (B.lookup(superR)) { // We do not extract the bit value from super region for now. return ValMgr.makeUnknownVal(); } + + if (R->hasHeapStorage()) { + // FIXME: If the region has heap storage and we know nothing special + // about its bindings, should we instead return UnknownVal? Seems like + // we should only return UndefinedVal in the cases where we know the value + // will be undefined. + return UndefinedVal(); + } + + if (R->hasStackStorage()) { + // Currently we don't reason specially about Clang-style vectors. Check + // if superR is a vector and if so return Unknown. + if (const TypedRegion *typedSuperR = dyn_cast<TypedRegion>(superR)) { + if (typedSuperR->getValueType(getContext())->isVectorType()) + return UnknownVal(); + } - if (R->hasHeapOrStackStorage()) return UndefinedVal(); + } QualType Ty = R->getValueType(getContext()); diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index 205bac2c82..07aa15e874 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -1,8 +1,7 @@ // RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=basic --verify -fblocks %s && -// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=range --verify -fblocks %s - -// NOWORK: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=basic --verify -fblocks %s && -// NOWORK: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s +// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=range --verify -fblocks %s && +// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=basic --verify -fblocks %s && +// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s typedef struct objc_selector *SEL; typedef signed char BOOL; |