diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/RegionStore.cpp | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index f0eac9dc2b..05d1bd0dcf 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -934,7 +934,7 @@ SVal RegionStoreManager::evalDynamicCast(SVal base, QualType derivedType, loc::MemRegionVal *baseRegVal = dyn_cast<loc::MemRegionVal>(&base); if (!baseRegVal) return UnknownVal(); - const MemRegion *BaseRegion = baseRegVal->stripCasts(); + const MemRegion *BaseRegion = baseRegVal->stripCasts(/*StripBases=*/false); // Assume the derived class is a pointer or a reference to a CXX record. derivedType = derivedType->getPointeeType(); @@ -957,23 +957,23 @@ SVal RegionStoreManager::evalDynamicCast(SVal base, QualType derivedType, if (SRDecl == DerivedDecl) return loc::MemRegionVal(TSR); - // If the region type is a subclass of the derived type. - if (!derivedType->isVoidType() && SRDecl->isDerivedFrom(DerivedDecl)) { - // This occurs in two cases. - // 1) We are processing an upcast. - // 2) We are processing a downcast but we jumped directly from the - // ancestor to a child of the cast value, so conjure the - // appropriate region to represent value (the intermediate node). - return loc::MemRegionVal(MRMgr.getCXXBaseObjectRegion(DerivedDecl, - BaseRegion)); - } + if (!derivedType->isVoidType()) { + // Static upcasts are marked as DerivedToBase casts by Sema, so this will + // only happen when multiple or virtual inheritance is involved. + // FIXME: We should build the correct stack of CXXBaseObjectRegions here, + // instead of just punting. + if (SRDecl->isDerivedFrom(DerivedDecl)) + return UnknownVal(); - // If super region is not a parent of derived class, the cast definitely - // fails. - if (!derivedType->isVoidType() && - DerivedDecl->isProvablyNotDerivedFrom(SRDecl)) { - Failed = true; - return UnknownVal(); + // If super region is not a parent of derived class, the cast definitely + // fails. + // FIXME: This and the above test each require walking the entire + // inheritance hierarchy, and this will happen for each + // CXXBaseObjectRegion wrapper. We should probably be combining the two. + if (DerivedDecl->isProvablyNotDerivedFrom(SRDecl)) { + Failed = true; + return UnknownVal(); + } } if (const CXXBaseObjectRegion *R = dyn_cast<CXXBaseObjectRegion>(TSR)) |