compiler: support go:noescape cross package
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 9 Jan 2018 23:26:27 +0000 (23:26 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 9 Jan 2018 23:26:27 +0000 (23:26 +0000)
    CL 83876 added support of go:noescape pragma, but it only works
    for functions called from the same package. The pragma did not
    take effect for exported functions that are not called from
    the same package. The reason is that top level function
    declarations are not traversed, and only reached from calls
    from other functions. This CL adds this support. The Traverse
    class is extended with a mode to traverse function declarations.

    Reviewed-on: https://go-review.googlesource.com/85637

From-SVN: r256405

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

index 6dbbf0f63c6e06c73ff88d39d1a7ae05aa6ceee8..70dfeebd31f4c40c66aa6d0a2535d946cec31d08 100644 (file)
@@ -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 5ba0b630b3ea1e55157c1db1635bbb3e2510fb33..7a0545108bb73c3322055f0dd6ebc60592a305eb 100644 (file)
@@ -997,13 +997,16 @@ class Escape_analysis_discover : public Traverse
 {
  public:
   Escape_analysis_discover(Gogo* gogo)
-    : Traverse(traverse_functions),
+    : Traverse(traverse_functions | traverse_func_declarations),
       gogo_(gogo), component_ids_()
   { }
 
   int
   function(Named_object*);
 
+  int
+  function_declaration(Named_object*);
+
   int
   visit(Named_object*);
 
@@ -1036,6 +1039,13 @@ Escape_analysis_discover::function(Named_object* 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
 // in this connected component.  If this is the root of the component,
 // create a set of functions to be analyzed later.
index cdb8b184368f6f13173b7764fd7439da2a2c9dc8..579b8a3ee5e3815541e0db1e320a134fe6c882fe 100644 (file)
@@ -7912,6 +7912,21 @@ Bindings::traverse(Traverse* traverse, bool is_global)
        }
     }
 
+  // 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;
 }
 
@@ -8221,6 +8236,12 @@ Traverse::type(Type*)
   go_unreachable();
 }
 
+int
+Traverse::function_declaration(Named_object*)
+{
+  go_unreachable();
+}
+
 // Class Statement_inserter.
 
 void
index 65762727989d9a7fca83d2657335aeeed723de8a..c16788cf4aea958cffb560e28ed725002357ee30 100644 (file)
@@ -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