compiler: scan all function literals for escape analysis
authorIan Lance Taylor <iant@golang.org>
Sun, 26 Jul 2020 18:08:13 +0000 (11:08 -0700)
committerIan Lance Taylor <iant@golang.org>
Mon, 27 Jul 2020 16:41:05 +0000 (09:41 -0700)
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

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/escape.cc

index d23e737..0fa32a4 100644 (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.
index 0d38858..8962f3f 100644 (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)