diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-10-10 22:36:28 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-10-10 22:36:28 +0000 |
commit | e50b01531afcb4afc40d27720afa09613ddcdfa2 (patch) | |
tree | 777dcbe1d08aec98253a00523c53b55cafbb49d1 /lib/Sema/SemaStmt.cpp | |
parent | 57165bea7cdbafdafe0e8e4c4b174f4abba29f7b (diff) |
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!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141586 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 7abfdd09de..5351896204 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/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); |