aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/RegionStore.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2013-03-19 22:38:09 +0000
committerAnna Zaks <ganna@apple.com>2013-03-19 22:38:09 +0000
commit9f3495aeaa24da4eacf8f6c274adcef65e2f3617 (patch)
treeec1bba9529f75f44ffc3fae681c24d147a71b0e4 /lib/StaticAnalyzer/Core/RegionStore.cpp
parent6e65e1047f861d4db87ad0154c171ac66d53b649 (diff)
[analyzer] Do not believe lazy binding when symbolic region types do not match
This fixes a crash when analyzing LLVM that was exposed by r177220 (modeling of trivial copy/move assignment operators). When we look up a lazy binding for “Builder”, we see the direct binding of Loc at offset 0. Previously, we believed the binding, which led to a crash. Now, we do not believe it as the types do not match. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177453 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp21
1 files changed, 16 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index 82db23dd6b..731c3ed8cc 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -1265,6 +1265,17 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T)
return svalBuilder.getRegionValueSymbolVal(R);
}
+static QualType getUnderlyingType(const SubRegion *R) {
+ QualType RegionTy;
+ if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R))
+ RegionTy = TVR->getValueType();
+
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
+ RegionTy = SR->getSymbol()->getType();
+
+ return RegionTy;
+}
+
/// Checks to see if store \p B has a lazy binding for region \p R.
///
/// If \p AllowSubregionBindings is \c false, a lazy binding will be rejected
@@ -1283,11 +1294,11 @@ getExistingLazyBinding(SValBuilder &SVB, RegionBindingsConstRef B,
if (!LCV)
return None;
- // If the LCV is for a subregion, the types won't match, and we shouldn't
- // reuse the binding. Unfortuately we can only check this if the destination
- // region is a TypedValueRegion.
- if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) {
- QualType RegionTy = TVR->getValueType();
+ // If the LCV is for a subregion, the types might not match, and we shouldn't
+ // reuse the binding.
+ QualType RegionTy = getUnderlyingType(R);
+ if (!RegionTy.isNull() &&
+ !RegionTy->isVoidPointerType()) {
QualType SourceRegionTy = LCV->getRegion()->getValueType();
if (!SVB.getContext().hasSameUnqualifiedType(RegionTy, SourceRegionTy))
return None;