From: Ted Kremenek Date: Wed, 18 Jul 2012 05:57:33 +0000 (+0000) Subject: Fix crash in RegionStoreManager::evalDerivedToBase() due to not handling references X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=21625c69e88d232e71a3bd4ba9d4bbb484183bf1;p=clang Fix crash in RegionStoreManager::evalDerivedToBase() due to not handling references (in uses of dynamic_cast<>). Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160427 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index c084bd2ad0..3dc7f7f58d 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -877,10 +877,22 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) { return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, ArrayR, Ctx)); } +// This mirrors Type::getCXXRecordDeclForPointerType(), but there doesn't +// appear to be another need for this in the rest of the codebase. +static const CXXRecordDecl *GetCXXRecordDeclForReferenceType(QualType Ty) { + if (const ReferenceType *RT = Ty->getAs()) + if (const RecordType *RCT = RT->getPointeeType()->getAs()) + return dyn_cast(RCT->getDecl()); + return 0; +} + SVal RegionStoreManager::evalDerivedToBase(SVal derived, QualType baseType) { const CXXRecordDecl *baseDecl; + if (baseType->isPointerType()) baseDecl = baseType->getCXXRecordDeclForPointerType(); + else if (baseType->isReferenceType()) + baseDecl = GetCXXRecordDeclForReferenceType(baseType); else baseDecl = baseType->getAsCXXRecordDecl(); diff --git a/test/Analysis/misc-ps-cxx0x.cpp b/test/Analysis/misc-ps-cxx0x.cpp index b4dee3122e..7712bb8dc3 100644 --- a/test/Analysis/misc-ps-cxx0x.cpp +++ b/test/Analysis/misc-ps-cxx0x.cpp @@ -73,3 +73,18 @@ void test2() { struct RDar11178609 { ~RDar11178609() = delete; }; + +// Tests that dynamic_cast handles references to C++ classes. Previously +// this crashed. +class rdar11817693_BaseBase {}; +class rdar11817693_BaseInterface {}; +class rdar11817693_Base : public rdar11817693_BaseBase, public rdar11817693_BaseInterface {}; +class rdar11817693 : public rdar11817693_Base { + virtual void operator=(const rdar11817693_BaseBase& src); + void operator=(const rdar11817693& src); +}; +void rdar11817693::operator=(const rdar11817693& src) { + operator=(dynamic_cast(src)); +} + +