diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-05-11 14:23:36 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-05-11 14:23:36 +0000 |
commit | c87d5fbfef92c96371c661cb12783c9590a91928 (patch) | |
tree | 4834a4b1062da92360d5f6e61f4e8cb5fdd50d43 | |
parent | 2ee5214779aafabb5058aa62e73e037d21880e6d (diff) |
When retrieving an ElementRegion, if its super region is a StringRegion,
retrieve the string value.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71430 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 84c8195ecb..9d29a90b3e 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -736,6 +736,24 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { if (state.contains<RegionKills>(R)) return UnknownVal(); + // Check if the region is an element region of a string literal. + if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { + if (const StringRegion *StrR=dyn_cast<StringRegion>(ER->getSuperRegion())) { + const StringLiteral *Str = StrR->getStringLiteral(); + SVal Idx = ER->getIndex(); + if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) { + int64_t i = CI->getValue().getSExtValue(); + char c; + if (i == Str->getByteLength()) + c = '\0'; + else + c = Str->getStrData()[i]; + const llvm::APSInt &V = getBasicVals().getValue(c, getContext().CharTy); + return nonloc::ConcreteInt(V); + } + } + } + // If the region is an element or field, it may have a default value. if (isa<ElementRegion>(R) || isa<FieldRegion>(R)) { const MemRegion* SuperR = cast<SubRegion>(R)->getSuperRegion(); |