summaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/Store.cpp
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2018-09-26 00:17:14 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2018-09-26 00:17:14 +0000
commit8e0f894a0e674223969246d91e61416de9bfb133 (patch)
tree846a369fbbdec75f1774fa34ab108e07ea75c739 /lib/StaticAnalyzer/Core/Store.cpp
parentc531bbd2d9553f1f337d9deb8fe0a9b6905dd2f4 (diff)
downloadclang-8e0f894a0e674223969246d91e61416de9bfb133.tar.gz
[analyzer] Fix a crash on casting symbolic pointers to derived classes.
Commit r340984 causes a crash when a pointer to a completely unrelated type UnrelatedT (eg., opaque struct pattern) is being casted from base class BaseT to derived class DerivedT, which results in an ill-formed region Derived{SymRegion{$<UnrelatedT x>}, DerivedT}. Differential Revision: https://reviews.llvm.org/D52189 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@343051 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/Store.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/Store.cpp12
1 files changed, 11 insertions, 1 deletions
diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp
index c3b706d90f..cc9939a68d 100644
--- a/lib/StaticAnalyzer/Core/Store.cpp
+++ b/lib/StaticAnalyzer/Core/Store.cpp
@@ -375,8 +375,18 @@ SVal StoreManager::attemptDownCast(SVal Base, QualType TargetType,
MR = Uncasted;
}
+ // If we're casting a symbolic base pointer to a derived class, use
+ // CXXDerivedObjectRegion to represent the cast. If it's a pointer to an
+ // unrelated type, it must be a weird reinterpret_cast and we have to
+ // be fine with ElementRegion. TODO: Should we instead make
+ // Derived{TargetClass, Element{SourceClass, SR}}?
if (const auto *SR = dyn_cast<SymbolicRegion>(MR)) {
- return loc::MemRegionVal(MRMgr.getCXXDerivedObjectRegion(TargetClass, SR));
+ QualType T = SR->getSymbol()->getType();
+ const CXXRecordDecl *SourceClass = T->getPointeeCXXRecordDecl();
+ if (TargetClass && SourceClass && TargetClass->isDerivedFrom(SourceClass))
+ return loc::MemRegionVal(
+ MRMgr.getCXXDerivedObjectRegion(TargetClass, SR));
+ return loc::MemRegionVal(GetElementZeroRegion(SR, TargetType));
}
// We failed if the region we ended up with has perfect type info.