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
This commit is contained in:
Ian Lance Taylor 2020-07-26 11:08:13 -07:00
parent bc4ed079dc
commit 8939cef951
2 changed files with 19 additions and 12 deletions

View File

@ -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.

View File

@ -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)