summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-08-13 22:11:42 +0000
committerJordan Rose <jordan_rose@apple.com>2012-08-13 22:11:42 +0000
commit574ef152fc3d53c715035c8126ae5862d636c8df (patch)
tree77ef2843614ed9406c425105d840ab09d2b775d2 /clang/lib/StaticAnalyzer
parent07a7ed80cb423e0d58f9f5217b8342b14c0b3e00 (diff)
downloadbcm5719-llvm-574ef152fc3d53c715035c8126ae5862d636c8df.tar.gz
bcm5719-llvm-574ef152fc3d53c715035c8126ae5862d636c8df.zip
[analyzer] Handle dynamic_casts that turn out to be upcasts.
This can occur with multiple inheritance, which jumps from one parent to the other, and with virtual inheritance, since virtual base regions always wrap the actual object and can't be nested within other base regions. This also exposed some incorrect logic for multiple inheritance: even if B is known not to derive from C, D might still derive from both of them. llvm-svn: 161798
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r--clang/lib/StaticAnalyzer/Core/RegionStore.cpp24
1 files changed, 11 insertions, 13 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index 05d1bd0dcff..bc4e4bbf602 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/CXXInheritance.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Basic/TargetInfo.h"
@@ -960,19 +961,16 @@ SVal RegionStoreManager::evalDynamicCast(SVal base, QualType derivedType,
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.
- // 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();
+ CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true,
+ /*DetectVirtual=*/false);
+ if (SRDecl->isDerivedFrom(DerivedDecl, Paths)) {
+ SVal Result = loc::MemRegionVal(TSR);
+ const CXXBasePath &Path = *Paths.begin();
+ for (CXXBasePath::const_iterator I = Path.begin(), E = Path.end();
+ I != E; ++I) {
+ Result = evalDerivedToBase(Result, I->Base->getType());
+ }
+ return Result;
}
}
OpenPOWER on IntegriCloud