From e50b01531afcb4afc40d27720afa09613ddcdfa2 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 10 Oct 2011 22:36:28 +0000 Subject: [PATCH] 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 --- lib/Sema/SemaStmt.cpp | 44 ++++++++++++++++++++++++++++++++----------- 1 file 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); -- 2.50.1