aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-05-06 16:48:20 +0000
committerJordan Rose <jordan_rose@apple.com>2013-05-06 16:48:20 +0000
commit6376703eb3325fe41233aed234fde81164af42a1 (patch)
tree0f214678f63f7f3eb4dcfd44bc68d024a7def91f /lib
parent2624b8157660902303bfce5551cfdd38272d01e5 (diff)
[analyzer] Handle CXXTemporaryObjectExprs in compound literals.
This occurs because in C++11 the compound literal syntax can trigger a constructor call via list-initialization. That is, "Point{x, y}" and "(Point){x, y}" end up being equivalent. If this occurs, the inner CXXConstructExpr will have already handled the object construction; the CompoundLiteralExpr just needs to propagate that value forwards. <rdar://problem/13804098> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181213 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp44
1 files changed, 25 insertions, 19 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 2d52c01e1d..67aeab6003 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -403,26 +403,32 @@ void ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
ExplodedNodeSet &Dst) {
StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
- const InitListExpr *ILE
- = cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
+ ProgramStateRef State = Pred->getState();
+ const LocationContext *LCtx = Pred->getLocationContext();
+
+ const Expr *Init = CL->getInitializer();
+ SVal V = State->getSVal(CL->getInitializer(), LCtx);
- ProgramStateRef state = Pred->getState();
- SVal ILV = state->getSVal(ILE, Pred->getLocationContext());
- const LocationContext *LC = Pred->getLocationContext();
- state = state->bindCompoundLiteral(CL, LC, ILV);
-
- // Compound literal expressions are a GNU extension in C++.
- // Unlike in C, where CLs are lvalues, in C++ CLs are prvalues,
- // and like temporary objects created by the functional notation T()
- // CLs are destroyed at the end of the containing full-expression.
- // HOWEVER, an rvalue of array type is not something the analyzer can
- // reason about, since we expect all regions to be wrapped in Locs.
- // So we treat array CLs as lvalues as well, knowing that they will decay
- // to pointers as soon as they are used.
- if (CL->isGLValue() || CL->getType()->isArrayType())
- B.generateNode(CL, Pred, state->BindExpr(CL, LC, state->getLValue(CL, LC)));
- else
- B.generateNode(CL, Pred, state->BindExpr(CL, LC, ILV));
+ if (isa<CXXConstructExpr>(Init)) {
+ // No work needed. Just pass the value up to this expression.
+ } else {
+ assert(isa<InitListExpr>(Init));
+ Loc CLLoc = State->getLValue(CL, LCtx);
+ State = State->bindLoc(CLLoc, V);
+
+ // Compound literal expressions are a GNU extension in C++.
+ // Unlike in C, where CLs are lvalues, in C++ CLs are prvalues,
+ // and like temporary objects created by the functional notation T()
+ // CLs are destroyed at the end of the containing full-expression.
+ // HOWEVER, an rvalue of array type is not something the analyzer can
+ // reason about, since we expect all regions to be wrapped in Locs.
+ // So we treat array CLs as lvalues as well, knowing that they will decay
+ // to pointers as soon as they are used.
+ if (CL->isGLValue() || CL->getType()->isArrayType())
+ V = CLLoc;
+ }
+
+ B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V));
}
void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,