@@ -381,44 +381,48 @@ CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S,
381381 bool GetLast,
382382 AggValueSlot AggSlot) {
383383
384- for (CompoundStmt::const_body_iterator I = S.body_begin (),
385- E = S. body_end ()- GetLast; I != E; ++I)
386- EmitStmt (*I );
384+ const Stmt *ExprResult = S.getStmtExprResult ();
385+ assert ((!GetLast || ( GetLast && ExprResult)) &&
386+ " If GetLast is true then the CompoundStmt must have a StmtExprResult " );
387387
388388 Address RetAlloca = Address::invalid ();
389- if (GetLast) {
390- // We have to special case labels here. They are statements, but when put
391- // at the end of a statement expression, they yield the value of their
392- // subexpression. Handle this by walking through all labels we encounter,
393- // emitting them before we evaluate the subexpr.
394- // Similar issues arise for attributed statements.
395- const Stmt *LastStmt = S.body_back ();
396- while (!isa<Expr>(LastStmt)) {
397- if (const auto *LS = dyn_cast<LabelStmt>(LastStmt)) {
398- EmitLabel (LS->getDecl ());
399- LastStmt = LS->getSubStmt ();
400- } else if (const auto *AS = dyn_cast<AttributedStmt>(LastStmt)) {
401- // FIXME: Update this if we ever have attributes that affect the
402- // semantics of an expression.
403- LastStmt = AS->getSubStmt ();
404- } else {
405- llvm_unreachable (" unknown value statement" );
389+
390+ for (auto *CurStmt : S.body ()) {
391+ if (GetLast && ExprResult == CurStmt) {
392+ // We have to special case labels here. They are statements, but when put
393+ // at the end of a statement expression, they yield the value of their
394+ // subexpression. Handle this by walking through all labels we encounter,
395+ // emitting them before we evaluate the subexpr.
396+ // Similar issues arise for attributed statements.
397+ while (!isa<Expr>(ExprResult)) {
398+ if (const auto *LS = dyn_cast<LabelStmt>(ExprResult)) {
399+ EmitLabel (LS->getDecl ());
400+ ExprResult = LS->getSubStmt ();
401+ } else if (const auto *AS = dyn_cast<AttributedStmt>(ExprResult)) {
402+ // FIXME: Update this if we ever have attributes that affect the
403+ // semantics of an expression.
404+ ExprResult = AS->getSubStmt ();
405+ } else {
406+ llvm_unreachable (" unknown value statement" );
407+ }
406408 }
407- }
408409
409- EnsureInsertPoint ();
410+ EnsureInsertPoint ();
410411
411- const Expr *E = cast<Expr>(LastStmt);
412- QualType ExprTy = E->getType ();
413- if (hasAggregateEvaluationKind (ExprTy)) {
414- EmitAggExpr (E, AggSlot);
412+ const Expr *E = cast<Expr>(ExprResult);
413+ QualType ExprTy = E->getType ();
414+ if (hasAggregateEvaluationKind (ExprTy)) {
415+ EmitAggExpr (E, AggSlot);
416+ } else {
417+ // We can't return an RValue here because there might be cleanups at
418+ // the end of the StmtExpr. Because of that, we have to emit the result
419+ // here into a temporary alloca.
420+ RetAlloca = CreateMemTemp (ExprTy);
421+ EmitAnyExprToMem (E, RetAlloca, Qualifiers (),
422+ /* IsInit*/ false );
423+ }
415424 } else {
416- // We can't return an RValue here because there might be cleanups at
417- // the end of the StmtExpr. Because of that, we have to emit the result
418- // here into a temporary alloca.
419- RetAlloca = CreateMemTemp (ExprTy);
420- EmitAnyExprToMem (E, RetAlloca, Qualifiers (),
421- /* IsInit*/ false );
425+ EmitStmt (CurStmt);
422426 }
423427 }
424428
0 commit comments