aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExprEngineCXX.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/ExprEngineCXX.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/ExprEngineCXX.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCXX.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index e7d59ebf57..32b522cbd5 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -34,12 +34,17 @@ void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
// If the value is already a CXXTempObjectRegion, it is fine as it is.
// Otherwise, create a new CXXTempObjectRegion, and copy the value into it.
+ // This is an optimization for when an rvalue is constructed and then
+ // immediately materialized.
const MemRegion *MR = V.getAsRegion();
- if (MR && isa<CXXTempObjectRegion>(MR))
- state = state->BindExpr(ME, LCtx, V);
- else
- state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME);
+ if (const CXXTempObjectRegion *TR =
+ dyn_cast_or_null<CXXTempObjectRegion>(MR)) {
+ if (getContext().hasSameUnqualifiedType(TR->getValueType(), ME->getType()))
+ state = state->BindExpr(ME, LCtx, V);
+ }
+ if (state == Pred->getState())
+ state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME);
Bldr.generateNode(ME, Pred, state);
}