diff mbox series

Go patch committed: Support go:noescape cross package

Message ID CAOyqgcVZEUGyq6d=x8tOKrQQAmY-hkz_bEQ5ff=qx_9RhgtMFw@mail.gmail.com
State New
Headers show
Series Go patch committed: Support go:noescape cross package | expand

Commit Message

Ian Lance Taylor Jan. 9, 2018, 11:26 p.m. UTC
This patch to the Go frontend by Cherry Zhang adds support for the
go:noescape compilation pragma across packages.
https://golang.org/cl/83876 added support for the go:noescape pragma,
but only for functions called from the same package.  The pragma did
not take effect for exported functions that are not called from the
same package.  This  is because top level function declarations are
not traversed, and are only reached from calls from other functions.
This patch adds support for uncalled function declarations.  The
Traverse class is extended with a mode to traverse function
declarations.  Bootstrapped on x86_64-pc-linux-gnu.  Committed to
mainline.

Ian
diff mbox series

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 256404)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-b361bec95927fd6209c286906f98deeedcfe1da3
+cf5a64066fa21b20beae0b895c05d26af53e13e0
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/escape.cc
===================================================================
--- gcc/go/gofrontend/escape.cc	(revision 256393)
+++ gcc/go/gofrontend/escape.cc	(working copy)
@@ -997,7 +997,7 @@  class Escape_analysis_discover : public
 {
  public:
   Escape_analysis_discover(Gogo* gogo)
-    : Traverse(traverse_functions),
+    : Traverse(traverse_functions | traverse_func_declarations),
       gogo_(gogo), component_ids_()
   { }
 
@@ -1005,6 +1005,9 @@  class Escape_analysis_discover : public
   function(Named_object*);
 
   int
+  function_declaration(Named_object*);
+
+  int
   visit(Named_object*);
 
   int
@@ -1034,6 +1037,13 @@  Escape_analysis_discover::function(Named
 {
   this->visit(fn);
   return TRAVERSE_CONTINUE;
+}
+
+int
+Escape_analysis_discover::function_declaration(Named_object* fn)
+{
+  this->visit(fn);
+  return TRAVERSE_CONTINUE;
 }
 
 // Visit a function FN, adding it to the current stack of functions
Index: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc	(revision 256398)
+++ gcc/go/gofrontend/gogo.cc	(working copy)
@@ -7912,6 +7912,21 @@  Bindings::traverse(Traverse* traverse, b
 	}
     }
 
+  // Traverse function declarations when needed.
+  if ((traverse_mask & Traverse::traverse_func_declarations) != 0)
+    {
+      for (Bindings::const_declarations_iterator p = this->begin_declarations();
+           p != this->end_declarations();
+           ++p)
+        {
+          if (p->second->is_function_declaration())
+            {
+              if (traverse->function_declaration(p->second) == TRAVERSE_EXIT)
+                return TRAVERSE_EXIT;
+            }
+        }
+    }
+
   return TRAVERSE_CONTINUE;
 }
 
@@ -8220,6 +8235,12 @@  Traverse::type(Type*)
 {
   go_unreachable();
 }
+
+int
+Traverse::function_declaration(Named_object*)
+{
+  go_unreachable();
+}
 
 // Class Statement_inserter.
 
Index: gcc/go/gofrontend/gogo.h
===================================================================
--- gcc/go/gofrontend/gogo.h	(revision 256398)
+++ gcc/go/gofrontend/gogo.h	(working copy)
@@ -3271,13 +3271,14 @@  class Traverse
 {
  public:
   // These bitmasks say what to traverse.
-  static const unsigned int traverse_variables =    0x1;
-  static const unsigned int traverse_constants =    0x2;
-  static const unsigned int traverse_functions =    0x4;
-  static const unsigned int traverse_blocks =       0x8;
-  static const unsigned int traverse_statements =  0x10;
-  static const unsigned int traverse_expressions = 0x20;
-  static const unsigned int traverse_types =       0x40;
+  static const unsigned int traverse_variables =          0x1;
+  static const unsigned int traverse_constants =          0x2;
+  static const unsigned int traverse_functions =          0x4;
+  static const unsigned int traverse_blocks =             0x8;
+  static const unsigned int traverse_statements =        0x10;
+  static const unsigned int traverse_expressions =       0x20;
+  static const unsigned int traverse_types =             0x40;
+  static const unsigned int traverse_func_declarations = 0x80;
 
   Traverse(unsigned int traverse_mask)
     : traverse_mask_(traverse_mask), types_seen_(NULL), expressions_seen_(NULL)
@@ -3342,6 +3343,11 @@  class Traverse
   virtual int
   type(Type*);
 
+  // If traverse_func_declarations is set in the mask, this is called
+  // for every function declarations in the tree.
+  virtual int
+  function_declaration(Named_object*);
+
  private:
   // A hash table for types we have seen during this traversal.  Note
   // that this uses the default hash functions for pointers rather