From 69ece336b8c06b71102e25f0d5770032d31b54cd Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Wed, 26 Sep 2018 00:17:14 +0000 Subject: [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{$}, DerivedT}. Differential Revision: https://reviews.llvm.org/D52189 llvm-svn: 343051 --- clang/lib/StaticAnalyzer/Core/Store.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'clang/lib/StaticAnalyzer/Core/Store.cpp') diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp index c3b706d90f6..cc9939a68dc 100644 --- a/clang/lib/StaticAnalyzer/Core/Store.cpp +++ b/clang/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(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. -- cgit v1.2.3