diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-05-06 16:48:20 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-05-06 16:48:20 +0000 |
commit | 5d2abefb621e819c7c60a0fdb351330486151c18 (patch) | |
tree | 8bb1dea050ad741ef235f83bd471a36b7c143f6b /clang/lib/StaticAnalyzer/Core | |
parent | 6c0505e4eb7ac4be17f6a6548ae843b2bb7bf01d (diff) | |
download | bcm5719-llvm-5d2abefb621e819c7c60a0fdb351330486151c18.tar.gz bcm5719-llvm-5d2abefb621e819c7c60a0fdb351330486151c18.zip |
[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>
llvm-svn: 181213
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 2d52c01e1d2..67aeab60033 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/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, |