r176069 - [analyzer] Don't look through casts when creating pointer temporaries.
Jordan Rose
jordan_rose at apple.com
Mon Feb 25 17:21:27 PST 2013
Author: jrose
Date: Mon Feb 25 19:21:27 2013
New Revision: 176069
URL: http://llvm.org/viewvc/llvm-project?rev=176069&view=rev
Log:
[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.
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/test/Analysis/temporaries.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=176069&r1=176068&r2=176069&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Feb 25 19:21:27 2013
@@ -182,14 +182,16 @@ ExprEngine::createTemporaryRegionIfNeede
// 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, Ex
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);
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=176069&r1=176068&r2=176069&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Mon Feb 25 19:21:27 2013
@@ -34,12 +34,17 @@ void ExprEngine::CreateCXXTemporaryObjec
// 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);
}
Modified: cfe/trunk/test/Analysis/temporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temporaries.cpp?rev=176069&r1=176068&r2=176069&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/temporaries.cpp (original)
+++ cfe/trunk/test/Analysis/temporaries.cpp Mon Feb 25 19:21:27 2013
@@ -62,3 +62,17 @@ namespace rdar13265460 {
}
}
+namespace rdar13281951 {
+ struct Derived : public Trivial {
+ Derived(int value) : Trivial(value), value2(-value) {}
+ int value2;
+ };
+
+ void test() {
+ Derived obj(1);
+ obj.value = 42;
+ const Trivial * const &pointerRef = &obj;
+ clang_analyzer_eval(pointerRef->value == 42); // expected-warning{{TRUE}}
+ }
+}
+
More information about the cfe-commits
mailing list