diff options
author | Ian Lance Taylor <iant@golang.org> | 2020-07-26 11:08:13 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-07-27 09:41:05 -0700 |
commit | 8939cef9512704dfd18d97ad3e66d6ce233e9452 (patch) | |
tree | 9d7be73b3fd4c744798ac64aa041526599e86c33 /gcc | |
parent | bc4ed079dc09a62168699227a794ac52a5b6f6a4 (diff) | |
download | gcc-8939cef9512704dfd18d97ad3e66d6ce233e9452.zip gcc-8939cef9512704dfd18d97ad3e66d6ce233e9452.tar.gz gcc-8939cef9512704dfd18d97ad3e66d6ce233e9452.tar.bz2 |
compiler: scan all function literals for escape analysis
We were scanning only function literals with closures, but not all
function literals have closures.
Discovered because compiler failed building 1.15rc1, as there is a
function literal in the runtime package (p1 in hexdumpWords) that has
no closure and, without escape analysis, was forcing a variable to the
heap which is not permitted in the runtime.
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/244802
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/escape.cc | 29 |
2 files changed, 19 insertions, 12 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index d23e737..0fa32a4 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -587d4595e446c597efe97ccdc81b2f05cbc04a21 +e86f2cb5d6b1984fde345d6ade605e377fa38c04 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 0d38858..8962f3f 100644 --- a/gcc/go/gofrontend/escape.cc +++ b/gcc/go/gofrontend/escape.cc @@ -142,18 +142,22 @@ Node::ast_format(Gogo* gogo) const else if (this->expr() != NULL) { Expression* e = this->expr(); + bool is_call = e->call_expression() != NULL; if (is_call) - e->call_expression()->fn(); + e = e->call_expression()->fn(); Func_expression* fe = e->func_expression();; - - bool is_closure = fe != NULL && fe->closure() != NULL; - if (is_closure) + if (fe != NULL) { - if (is_call) - return "(func literal)()"; - return "func literal"; + Named_object* no = fe->named_object(); + if (no->is_function() && no->func_value()->enclosing() != NULL) + { + if (is_call) + return "(func literal)()"; + return "func literal"; + } } + Ast_dump_context::dump_to_stream(this->expr(), &ss); } else if (this->statement() != NULL) @@ -1172,11 +1176,14 @@ Escape_discover_expr::expression(Expression** pexpr) // Method call or function call. fn = e->call_expression()->fn()->func_expression()->named_object(); } - else if (e->func_expression() != NULL - && e->func_expression()->closure() != NULL) + else if (e->func_expression() != NULL) { - // Closure. - fn = e->func_expression()->named_object(); + Named_object* no = e->func_expression()->named_object(); + if (no->is_function() && no->func_value()->enclosing() != NULL) + { + // Nested function. + fn = no; + } } if (fn != NULL) |