summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/Store.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-02-15 01:23:24 +0000
committerJordan Rose <jordan_rose@apple.com>2013-02-15 01:23:24 +0000
commit5bc0dd79e148171ab054d134189bb9cb37147fec (patch)
treee989f8d3a7d9fa16e57a37aaed7ba553751dd3dc /clang/lib/StaticAnalyzer/Core/Store.cpp
parentf7d8d767fbbcd0d52644bdf4307c27a392855bf2 (diff)
downloadbcm5719-llvm-5bc0dd79e148171ab054d134189bb9cb37147fec.tar.gz
bcm5719-llvm-5bc0dd79e148171ab054d134189bb9cb37147fec.zip
[analyzer] Don't assert when mixing reinterpret_cast and derived-to-base casts.
This just adds a very simple check that if a DerivedToBase CastExpr is operating on a value with known C++ object type, and that type is not the base type specified in the AST, then the cast is invalid and we should return UnknownVal. In the future, perhaps we can have a checker that specifies that this is illegal, but we still shouldn't assert even if the user turns that checker off. PR14872 llvm-svn: 175239
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/Store.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/Store.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp
index e7e80dd01ed..128dce4988f 100644
--- a/clang/lib/StaticAnalyzer/Core/Store.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Store.cpp
@@ -223,7 +223,32 @@ const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy)
llvm_unreachable("unreachable");
}
+static bool regionMatchesCXXRecordType(SVal V, QualType Ty) {
+ const MemRegion *MR = V.getAsRegion();
+ if (!MR)
+ return true;
+
+ const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR);
+ if (!TVR)
+ return true;
+
+ const CXXRecordDecl *RD = TVR->getValueType()->getAsCXXRecordDecl();
+ if (!RD)
+ return true;
+
+ const CXXRecordDecl *Expected = Ty->getPointeeCXXRecordDecl();
+ if (!Expected)
+ Expected = Ty->getAsCXXRecordDecl();
+
+ return Expected->getCanonicalDecl() == RD->getCanonicalDecl();
+}
+
SVal StoreManager::evalDerivedToBase(SVal Derived, const CastExpr *Cast) {
+ // Sanity check to avoid doing the wrong thing in the face of
+ // reinterpret_cast.
+ if (!regionMatchesCXXRecordType(Derived, Cast->getSubExpr()->getType()))
+ return UnknownVal();
+
// Walk through the cast path to create nested CXXBaseRegions.
SVal Result = Derived;
for (CastExpr::path_const_iterator I = Cast->path_begin(),
OpenPOWER on IntegriCloud