Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision a93589218b787f36ca9d02a420b5d7b54ed5fc68)
+++ src/InitTweak/FixInit.cc	(revision 0e315a5bdd9f4a2506c85cc3c18350e2b93b270c)
@@ -72,4 +72,10 @@
 		};
 
+		struct StmtExprResult {
+			static void link( std::list< Declaration * > & translationUnit );
+
+			void previsit( StmtExpr * stmtExpr );
+		};
+
 		struct InsertImplicitCalls : public WithConstTypeSubstitution {
 			/// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
@@ -226,4 +232,7 @@
 		acceptAll( translationUnit, checker );
 
+		// fixes StmtExpr to properly link to their resulting expression
+		StmtExprResult::link( translationUnit );
+
 		// fixes ConstructorInit for global variables. should happen before fixInitializers.
 		InitTweak::fixGlobalInit( translationUnit, inLibrary );
@@ -299,4 +308,9 @@
 
 			return dtorFunc;
+		}
+
+		void StmtExprResult::link( std::list< Declaration * > & translationUnit ) {
+			PassVisitor<StmtExprResult> linker;
+			acceptAll( translationUnit, linker );
 		}
 
@@ -349,4 +363,15 @@
 			PassVisitor<FixCtorExprs> fixer;
 			mutateAll( translationUnit, fixer );
+		}
+
+		void StmtExprResult::previsit( StmtExpr * stmtExpr ) {
+			// we might loose the result expression here so add a pointer to trace back
+			assert( stmtExpr->result );
+			Type * result = stmtExpr->result;
+			if ( ! result->isVoid() ) {
+				CompoundStmt * body = stmtExpr->statements;
+				assert( ! body->kids.empty() );
+				stmtExpr->resultExpr = strict_dynamic_cast< ExprStmt * >( body->kids.back() );
+			}
 		}
 
@@ -655,7 +680,7 @@
 			// function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression,
 			// since temporaries can be shared across sub-expressions, e.g.
-			//   [A, A] f();
-			//   g([A] x, [A] y);
-			//   g(f());
+			//   [A, A] f();       // decl
+			//   g([A] x, [A] y);  // decl
+			//   g(f());           // call
 			// f is executed once, so the return temporary is shared across the tuple constructors for x and y.
 			// Explicitly mutating children instead of mutating the inner compound statement forces the temporaries to be added
@@ -665,4 +690,5 @@
 			assert( env );
 
+			indexer.enterScope();
 			// visit all statements
 			std::list< Statement * > & stmts = stmtExpr->statements->get_kids();
@@ -670,4 +696,5 @@
 				stmt = stmt->acceptMutator( *visitor );
 			} // for
+			indexer.leaveScope();
 
 			assert( stmtExpr->result );
@@ -688,10 +715,19 @@
 				stmtsToAddBefore.push_back( new DeclStmt( ret ) );
 
-				// must have a non-empty body, otherwise it wouldn't have a result
-				CompoundStmt * body = stmtExpr->statements;
-				assert( ! body->kids.empty() );
-				// must be an ExprStmt, otherwise it wouldn't have a result
-				ExprStmt * last = strict_dynamic_cast< ExprStmt * >( body->kids.back() );
-				last->expr = makeCtorDtor( "?{}", ret, last->expr );
+				if(!stmtExpr->resultExpr) {
+					SemanticError(stmtExpr, "Statment-Expression should have a resulting expression");
+				}
+				ExprStmt * last = stmtExpr->resultExpr;
+				try {
+					last->expr = makeCtorDtor( "?{}", ret, last->expr );
+				} catch(...) {
+					std::cerr << "=======================" << std::endl;
+					std::cerr << "ERROR, can't resolve" << std::endl;
+					ret->print(std::cerr);
+					std::cerr << std::endl << "---" << std::endl;
+					last->expr->print(std::cerr);
+
+					abort();
+				}
 
 				// add destructors after current statement
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision a93589218b787f36ca9d02a420b5d7b54ed5fc68)
+++ src/SynTree/Expression.cc	(revision 0e315a5bdd9f4a2506c85cc3c18350e2b93b270c)
@@ -610,5 +610,5 @@
 	computeResult();
 }
-StmtExpr::StmtExpr( const StmtExpr & other ) : Expression( other ), statements( other.statements->clone() ) {
+StmtExpr::StmtExpr( const StmtExpr & other ) : Expression( other ), statements( other.statements->clone() ), resultExpr( other.resultExpr ) {
 	cloneAll( other.returnDecls, returnDecls );
 	cloneAll( other.dtors, dtors );
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision a93589218b787f36ca9d02a420b5d7b54ed5fc68)
+++ src/SynTree/Expression.h	(revision 0e315a5bdd9f4a2506c85cc3c18350e2b93b270c)
@@ -62,5 +62,5 @@
 	InferredParams inferParams;       ///< Post-resolution inferred parameter slots
 	std::vector<UniqueId> resnSlots;  ///< Pre-resolution inferred parameter slots
-	
+
 	// xxx - should turn inferParams+resnSlots into a union to save some memory
 
@@ -744,4 +744,7 @@
 	std::list< Expression * > dtors; // destructor(s) for return variable(s)
 
+	// readonly
+	ExprStmt * resultExpr = nullptr;
+
 	StmtExpr( CompoundStmt * statements );
 	StmtExpr( const StmtExpr & other );
