aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2009-05-11 14:23:36 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2009-05-11 14:23:36 +0000
commitc87d5fbfef92c96371c661cb12783c9590a91928 (patch)
tree4834a4b1062da92360d5f6e61f4e8cb5fdd50d43
parent2ee5214779aafabb5058aa62e73e037d21880e6d (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.cpp18
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();