diff options
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/escape.cc | 9 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 2 |
3 files changed, 11 insertions, 2 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index fe3c16e..80ccaf3 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -d5774539b17112d9ce709a1fe722daf68eb8594f +7c5e4d67041e3529a055a923b2b9f5ef09aa72a3 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/escape.cc b/gcc/go/gofrontend/escape.cc index 7a05451..65ccf9b 100644 --- a/gcc/go/gofrontend/escape.cc +++ b/gcc/go/gofrontend/escape.cc @@ -1420,7 +1420,14 @@ Escape_analysis_assign::statement(Block*, size_t*, Statement* s) case Statement::STATEMENT_DEFER: if (this->context_->loop_depth() == 1) - break; + { + // Defer statement may need to allocate a thunk. When it is + // not inside a loop, this can be stack allocated, as it + // runs before the function finishes. + Node* n = Node::make_node(s); + n->set_encoding(Node::ESCAPE_NONE); + break; + } // fallthrough case Statement::STATEMENT_GO: diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 93718ff..1c079bb 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -2156,6 +2156,8 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function, // Allocate the initialized struct on the heap. constructor = Expression::make_heap_expression(constructor, location); + if ((Node::make_node(this)->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE) + constructor->heap_expression()->set_allocate_on_stack(); // Throw an error if the function is nil. This is so that for `go // nil` we get a backtrace from the go statement, rather than a |