summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/Store.cpp
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2018-08-29 22:43:31 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2018-08-29 22:43:31 +0000
commit4e864b8329a73a323fd9e4cf28e702b7b10708b0 (patch)
tree2086a75d0e99391912e0f24799592fe7a135745a /clang/lib/StaticAnalyzer/Core/Store.cpp
parent1e4498869d7f4a9c22336bfe9ba50560831478d5 (diff)
downloadbcm5719-llvm-4e864b8329a73a323fd9e4cf28e702b7b10708b0.tar.gz
bcm5719-llvm-4e864b8329a73a323fd9e4cf28e702b7b10708b0.zip
[analyzer] Support modeling no-op BaseToDerived casts in ExprEngine.
Introduce a new MemRegion sub-class, CXXDerivedObjectRegion, which is the opposite of CXXBaseObjectRegion, to represent such casts. Such region is a bit weird because it is by design bigger than its super-region. But it's not harmful when it is put on top of a SymbolicRegion that has unknown extent anyway. Offset computation for CXXDerivedObjectRegion and proper modeling of casts still remains to be implemented. Differential Revision: https://reviews.llvm.org/D51191 llvm-svn: 340984
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/Store.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/Store.cpp22
1 files changed, 18 insertions, 4 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp
index 94188a9ef69..c3b706d90f6 100644
--- a/clang/lib/StaticAnalyzer/Core/Store.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Store.cpp
@@ -138,6 +138,7 @@ const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy)
case MemRegion::VarRegionKind:
case MemRegion::CXXTempObjectRegionKind:
case MemRegion::CXXBaseObjectRegionKind:
+ case MemRegion::CXXDerivedObjectRegionKind:
return MakeElementRegion(cast<SubRegion>(R), PointeeTy);
case MemRegion::ElementRegionKind: {
@@ -272,9 +273,8 @@ SVal StoreManager::evalDerivedToBase(SVal Derived, const CXXBasePath &Path) {
SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType,
bool IsVirtual) {
- Optional<loc::MemRegionVal> DerivedRegVal =
- Derived.getAs<loc::MemRegionVal>();
- if (!DerivedRegVal)
+ const MemRegion *DerivedReg = Derived.getAsRegion();
+ if (!DerivedReg)
return Derived;
const CXXRecordDecl *BaseDecl = BaseType->getPointeeCXXRecordDecl();
@@ -282,8 +282,18 @@ SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType,
BaseDecl = BaseType->getAsCXXRecordDecl();
assert(BaseDecl && "not a C++ object?");
+ if (const auto *AlreadyDerivedReg =
+ dyn_cast<CXXDerivedObjectRegion>(DerivedReg)) {
+ if (const auto *SR =
+ dyn_cast<SymbolicRegion>(AlreadyDerivedReg->getSuperRegion()))
+ if (SR->getSymbol()->getType()->getPointeeCXXRecordDecl() == BaseDecl)
+ return loc::MemRegionVal(SR);
+
+ DerivedReg = AlreadyDerivedReg->getSuperRegion();
+ }
+
const MemRegion *BaseReg = MRMgr.getCXXBaseObjectRegion(
- BaseDecl, cast<SubRegion>(DerivedRegVal->getRegion()), IsVirtual);
+ BaseDecl, cast<SubRegion>(DerivedReg), IsVirtual);
return loc::MemRegionVal(BaseReg);
}
@@ -365,6 +375,10 @@ SVal StoreManager::attemptDownCast(SVal Base, QualType TargetType,
MR = Uncasted;
}
+ if (const auto *SR = dyn_cast<SymbolicRegion>(MR)) {
+ return loc::MemRegionVal(MRMgr.getCXXDerivedObjectRegion(TargetClass, SR));
+ }
+
// We failed if the region we ended up with has perfect type info.
Failed = isa<TypedValueRegion>(MR);
return UnknownVal();
OpenPOWER on IntegriCloud