From patchwork Fri Oct 8 20:44:15 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [gccgo] Thunk statements need not be the only statements in a block Date: Fri, 08 Oct 2010 10:44:15 -0000 From: Ian Taylor X-Patchwork-Id: 67285 Message-Id: To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com The Go parser arranges for thunk statements (from go and defer statements in the language) to be the only statements in their block. The code which simplifies these statements was assuming that. However, it is possible for the passes which enforce order of evaluation to break the thunk statements into multiple statements. This patch fixes the simplification code to assume that the thunk statement is the last statement in the block, rather than assuming that it is the only statement in the block. Committed to gccgo branch. Ian diff -r 5f836c41c4e8 go/gogo.h --- a/go/gogo.h Fri Oct 08 13:37:52 2010 -0700 +++ b/go/gogo.h Fri Oct 08 13:42:06 2010 -0700 @@ -856,11 +856,6 @@ void determine_types(); - // Swap the block's statements with STATEMENTS. - void - swap_statements(std::vector& statements) - { this->statements_.swap(statements); } - // Return true if execution of this block may fall through to the // next block. bool diff -r 5f836c41c4e8 go/statements.cc --- a/go/statements.cc Fri Oct 08 13:37:52 2010 -0700 +++ b/go/statements.cc Fri Oct 08 13:42:06 2010 -0700 @@ -1768,11 +1768,11 @@ int Simplify_thunk_traverse::block(Block* b) { - // The parser ensures that thunk statements always appear in a block - // which has only a single statement. - if (b->statements()->size() != 1) + // The parser ensures that thunk statements always appear at the end + // of a block. + if (b->statements()->size() < 1) return TRAVERSE_CONTINUE; - Thunk_statement* stat = b->statements()->front()->thunk_statement(); + Thunk_statement* stat = b->statements()->back()->thunk_statement(); if (stat == NULL) return TRAVERSE_CONTINUE; if (stat->simplify_statement(this->gogo_, b)) @@ -1897,16 +1897,14 @@ else gcc_unreachable(); - // The current block should only have the go statement. - gcc_assert(block->statements()->size() == 1); - gcc_assert(block->statements()->front() == this); - std::vector statements; - statements.push_back(s); - block->swap_statements(statements); + // The current block should end with the go statement. + gcc_assert(block->statements()->size() >= 1); + gcc_assert(block->statements()->back() == this); + block->replace_statement(block->statements()->size() - 1, s); // We already ran the determine_types pass, so we need to run it now - // for this new block. - block->determine_types(); + // for the new statement. + s->determine_types(); // Sanity check. gogo->check_types_in_block(block);