aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-02-26 01:21:27 +0000
committerJordan Rose <jordan_rose@apple.com>2013-02-26 01:21:27 +0000
commiteafb5c694cc5d165149fcb9453bc9355fb0d44a5 (patch)
treed0ceda24813738b32f9757875fdabd88e8bbd626 /lib/StaticAnalyzer/Core/ExprEngine.cpp
parenta0e6e6dd37f4acee8477c106d5e5679de015d120 (diff)
[analyzer] Don't look through casts when creating pointer temporaries.
Normally, we need to look through derived-to-base casts when creating temporary object regions (added in r175854). However, if the temporary is a pointer (rather than a struct/class instance), we need to /preserve/ the base casts that have been applied. This also ensures that we really do create a new temporary region when we need to: MaterializeTemporaryExpr and lvalue CXXDefaultArgExprs. Fixes PR15342, although the test case doesn't include the crash because I couldn't isolate it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176069 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp19
1 files changed, 11 insertions, 8 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 8b6de13249..437af86ccf 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -182,14 +182,16 @@ ExprEngine::createTemporaryRegionIfNeeded(ProgramStateRef State,
// bindings for a base type. Start by stripping and recording base casts.
SmallVector<const CastExpr *, 4> Casts;
const Expr *Inner = Ex->IgnoreParens();
- while (const CastExpr *CE = dyn_cast<CastExpr>(Inner)) {
- if (CE->getCastKind() == CK_DerivedToBase ||
- CE->getCastKind() == CK_UncheckedDerivedToBase)
- Casts.push_back(CE);
- else if (CE->getCastKind() != CK_NoOp)
- break;
+ if (V.getAs<NonLoc>()) {
+ while (const CastExpr *CE = dyn_cast<CastExpr>(Inner)) {
+ if (CE->getCastKind() == CK_DerivedToBase ||
+ CE->getCastKind() == CK_UncheckedDerivedToBase)
+ Casts.push_back(CE);
+ else if (CE->getCastKind() != CK_NoOp)
+ break;
- Inner = CE->getSubExpr()->IgnoreParens();
+ Inner = CE->getSubExpr()->IgnoreParens();
+ }
}
// Create a temporary object region for the inner expression (which may have
@@ -703,7 +705,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
State = State->BindExpr(DefaultE, LCtx, V);
if (DefaultE->isGLValue())
- State = createTemporaryRegionIfNeeded(State, LCtx, DefaultE);
+ State = createTemporaryRegionIfNeeded(State, LCtx, DefaultE,
+ DefaultE);
Bldr2.generateNode(S, *I, State);
}