summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-10-10 22:36:28 +0000
committerTed Kremenek <kremenek@apple.com>2011-10-10 22:36:28 +0000
commitbed648e0b005a42a8aee5b8cd897e2a67876c08a (patch)
tree6cd79b147ab3443d7a006d1a0ea79eb889bc25d7 /clang/lib
parent8ec0897db6d35ee756468c25157dce783324e186 (diff)
downloadbcm5719-llvm-bed648e0b005a42a8aee5b8cd897e2a67876c08a.tar.gz
bcm5719-llvm-bed648e0b005a42a8aee5b8cd897e2a67876c08a.zip
Rework construction of CXXForRangeStmt not to recycle the same DeclRefExpr in multiple subexpressions. This breaks the tree structure
of the AST and completely breaks the CFG invariants. Patch by Jim Goodnow II and reviewed by Richard Smith! llvm-svn: 141586
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaStmt.cpp44
1 files changed, 33 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 7abfdd09de5..5351896204c 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -1339,10 +1339,16 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
if (!BeginEndDecl.get() && !RangeVarType->isDependentType()) {
SourceLocation RangeLoc = RangeVar->getLocation();
- ExprResult RangeRef = BuildDeclRefExpr(RangeVar,
- RangeVarType.getNonReferenceType(),
- VK_LValue, ColonLoc);
- if (RangeRef.isInvalid())
+ const QualType RangeVarNonRefType = RangeVarType.getNonReferenceType();
+
+ ExprResult BeginRangeRef = BuildDeclRefExpr(RangeVar, RangeVarNonRefType,
+ VK_LValue, ColonLoc);
+ if (BeginRangeRef.isInvalid())
+ return StmtError();
+
+ ExprResult EndRangeRef = BuildDeclRefExpr(RangeVar, RangeVarNonRefType,
+ VK_LValue, ColonLoc);
+ if (EndRangeRef.isInvalid())
return StmtError();
QualType AutoType = Context.getAutoDeductType();
@@ -1370,8 +1376,8 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
// the program is ill-formed;
// begin-expr is __range.
- BeginExpr = RangeRef;
- if (FinishForRangeVarDecl(*this, BeginVar, RangeRef.get(), ColonLoc,
+ BeginExpr = BeginRangeRef;
+ if (FinishForRangeVarDecl(*this, BeginVar, BeginRangeRef.get(), ColonLoc,
diag::err_for_range_iter_deduction_failure)) {
NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
return StmtError();
@@ -1393,7 +1399,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
}
// end-expr is __range + __bound.
- EndExpr = ActOnBinOp(S, ColonLoc, tok::plus, RangeRef.get(),
+ EndExpr = ActOnBinOp(S, ColonLoc, tok::plus, EndRangeRef.get(),
BoundExpr.get());
if (EndExpr.isInvalid())
return StmtError();
@@ -1434,13 +1440,14 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
BeginExpr = BuildForRangeBeginEndCall(*this, S, ColonLoc, BeginVar,
BEF_begin, BeginNameInfo,
- BeginMemberLookup, RangeRef.get());
+ BeginMemberLookup,
+ BeginRangeRef.get());
if (BeginExpr.isInvalid())
return StmtError();
EndExpr = BuildForRangeBeginEndCall(*this, S, ColonLoc, EndVar,
BEF_end, EndNameInfo,
- EndMemberLookup, RangeRef.get());
+ EndMemberLookup, EndRangeRef.get());
if (EndExpr.isInvalid())
return StmtError();
}
@@ -1460,11 +1467,16 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
BuildDeclaratorGroup(BeginEndDecls, 2, /*TypeMayContainAuto=*/false);
BeginEndDecl = ActOnDeclStmt(BeginEndGroup, ColonLoc, ColonLoc);
- ExprResult BeginRef = BuildDeclRefExpr(BeginVar,
- BeginType.getNonReferenceType(),
+ const QualType BeginRefNonRefType = BeginType.getNonReferenceType();
+ ExprResult BeginRef = BuildDeclRefExpr(BeginVar, BeginRefNonRefType,
VK_LValue, ColonLoc);
+ if (BeginRef.isInvalid())
+ return StmtError();
+
ExprResult EndRef = BuildDeclRefExpr(EndVar, EndType.getNonReferenceType(),
VK_LValue, ColonLoc);
+ if (EndRef.isInvalid())
+ return StmtError();
// Build and check __begin != __end expression.
NotEqExpr = ActOnBinOp(S, ColonLoc, tok::exclaimequal,
@@ -1479,6 +1491,11 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
}
// Build and check ++__begin expression.
+ BeginRef = BuildDeclRefExpr(BeginVar, BeginRefNonRefType,
+ VK_LValue, ColonLoc);
+ if (BeginRef.isInvalid())
+ return StmtError();
+
IncrExpr = ActOnUnaryOp(S, ColonLoc, tok::plusplus, BeginRef.get());
IncrExpr = ActOnFinishFullExpr(IncrExpr.get());
if (IncrExpr.isInvalid()) {
@@ -1487,6 +1504,11 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
}
// Build and check *__begin expression.
+ BeginRef = BuildDeclRefExpr(BeginVar, BeginRefNonRefType,
+ VK_LValue, ColonLoc);
+ if (BeginRef.isInvalid())
+ return StmtError();
+
ExprResult DerefExpr = ActOnUnaryOp(S, ColonLoc, tok::star, BeginRef.get());
if (DerefExpr.isInvalid()) {
NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
OpenPOWER on IntegriCloud