From 41a6da2de5102b6052175c82ad2fb2357c9eceab Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 9 Jan 2018 23:26:27 +0000 Subject: [PATCH] compiler: support go:noescape cross package 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 | 2 +- gcc/go/gofrontend/escape.cc | 12 +++++++++++- gcc/go/gofrontend/gogo.cc | 21 +++++++++++++++++++++ gcc/go/gofrontend/gogo.h | 20 +++++++++++++------- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 6dbbf0f63c6..70dfeebd31f 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/escape.cc b/gcc/go/gofrontend/escape.cc index 5ba0b630b3e..7a0545108bb 100644 --- a/gcc/go/gofrontend/escape.cc +++ b/gcc/go/gofrontend/escape.cc @@ -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. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index cdb8b184368..579b8a3ee5e 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -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 diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 65762727989..c16788cf4ae 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -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 -- 2.30.2