aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-09-28 17:15:12 +0000
committerJordan Rose <jordan_rose@apple.com>2012-09-28 17:15:12 +0000
commit6f61df3e7256413dcb99afb9673f4206e3c4992c (patch)
treed297501092690e7a5b0e044191966f655dc30960 /lib/StaticAnalyzer/Core/ExprEngine.cpp
parentda3d76b4cfbb5ebeb79e03a0abeabd403fe9260a (diff)
[analyzer] Create a temporary region for rvalue structs when accessing fields
Struct rvalues are represented in the analyzer by CompoundVals, LazyCompoundVals, or plain ConjuredSymbols -- none of which have associated regions. If the entire structure is going to persist, this is not a problem -- either the rvalue will be assigned to an existing region, or a MaterializeTemporaryExpr will be present to create a temporary region. However, if we just need a field from the struct, we need to create the temporary region ourselves. This is inspired by the way CodeGen handles calls to temporaries; support for that in the analyzer is coming next. Part of <rdar://problem/12137950> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164828 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp18
1 files changed, 9 insertions, 9 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 8e2c159ca7..06216f83ea 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1505,17 +1505,17 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
ProgramStateRef state = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
SVal baseExprVal = state->getSVal(baseExpr, Pred->getLocationContext());
- if (isa<nonloc::LazyCompoundVal>(baseExprVal) ||
- isa<nonloc::CompoundVal>(baseExprVal) ||
- // FIXME: This can originate by conjuring a symbol for an unknown
- // temporary struct object, see test/Analysis/fields.c:
- // (p = getit()).x
- isa<nonloc::SymbolVal>(baseExprVal)) {
- Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, UnknownVal()));
- return;
+
+ // If we're accessing a field of an rvalue, we need to treat it like a
+ // temporary object.
+ if (isa<NonLoc>(baseExprVal)) {
+ const MemRegion *R =
+ svalBuilder.getRegionManager().getCXXTempObjectRegion(baseExpr, LCtx);
+ SVal L = loc::MemRegionVal(R);
+ state = state->bindLoc(L, baseExprVal);
+ baseExprVal = L;
}
- // For all other cases, compute an lvalue.
SVal L = state->getLValue(field, baseExprVal);
if (M->isGLValue()) {
ExplodedNodeSet Tmp;