public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-1022] compiler: mark global variables whose address is taken
@ 2021-05-24 20:25 Ian Lance Taylor
  0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2021-05-24 20:25 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:358832c46a378e5a0b8a2fa3c2739125e3e680c7

commit r12-1022-g358832c46a378e5a0b8a2fa3c2739125e3e680c7
Author: Ian Lance Taylor <iant@golang.org>
Date:   Sat May 22 19:19:13 2021 -0700

    compiler: mark global variables whose address is taken
    
    To implement this, change the backend to use flag bits for variables.
    
    Fixes https://gcc.gnu.org/PR100537
    
            PR go/100537
            * go-gcc.cc (class Gcc_backend): Update methods that create
            variables to take a flags parameter.
    
    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/322129

Diff:
---
 gcc/go/go-gcc.cc                 | 155 ++++++++++++++++++++++++++-------------
 gcc/go/gofrontend/MERGE          |   2 +-
 gcc/go/gofrontend/backend.h      | 145 +++++++++++++++++++-----------------
 gcc/go/gofrontend/expressions.cc |  63 +++++++++-------
 gcc/go/gofrontend/gogo.cc        |  54 ++++++++------
 gcc/go/gofrontend/statements.cc  |   6 +-
 gcc/go/gofrontend/types.cc       |  35 +++++----
 7 files changed, 276 insertions(+), 184 deletions(-)

diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 5d9dbb5d068..41f309e7294 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -415,47 +415,46 @@ class Gcc_backend : public Backend
   global_variable(const std::string& var_name,
 		  const std::string& asm_name,
 		  Btype* btype,
-		  bool is_external,
-		  bool is_hidden,
-		  bool in_unique_section,
+		  unsigned int flags,
 		  Location location);
 
   void
   global_variable_set_init(Bvariable*, Bexpression*);
 
   Bvariable*
-  local_variable(Bfunction*, const std::string&, Btype*, Bvariable*, bool,
-		 Location);
+  local_variable(Bfunction*, const std::string&, Btype*, Bvariable*,
+		 unsigned int, Location);
 
   Bvariable*
-  parameter_variable(Bfunction*, const std::string&, Btype*, bool,
+  parameter_variable(Bfunction*, const std::string&, Btype*, unsigned int,
 		     Location);
 
   Bvariable*
-  static_chain_variable(Bfunction*, const std::string&, Btype*, Location);
+  static_chain_variable(Bfunction*, const std::string&, Btype*, unsigned int,
+			Location);
 
   Bvariable*
-  temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
+  temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, unsigned int,
 		     Location, Bstatement**);
 
   Bvariable*
   implicit_variable(const std::string&, const std::string&, Btype*,
-                    bool, bool, bool, int64_t);
+                    unsigned int, int64_t);
 
   void
   implicit_variable_set_init(Bvariable*, const std::string&, Btype*,
-			     bool, bool, bool, Bexpression*);
+			     unsigned int, Bexpression*);
 
   Bvariable*
   implicit_variable_reference(const std::string&, const std::string&, Btype*);
 
   Bvariable*
   immutable_struct(const std::string&, const std::string&,
-                   bool, bool, Btype*, Location);
+                   unsigned int, Btype*, Location);
 
   void
-  immutable_struct_set_init(Bvariable*, const std::string&, bool, bool, Btype*,
-			    Location, Bexpression*);
+  immutable_struct_set_init(Bvariable*, const std::string&, unsigned int,
+			    Btype*, Location, Bexpression*);
 
   Bvariable*
   immutable_struct_reference(const std::string&, const std::string&,
@@ -2696,9 +2695,7 @@ Bvariable*
 Gcc_backend::global_variable(const std::string& var_name,
 			     const std::string& asm_name,
 			     Btype* btype,
-			     bool is_external,
-			     bool is_hidden,
-			     bool in_unique_section,
+			     unsigned int flags,
 			     Location location)
 {
   tree type_tree = btype->get_tree();
@@ -2707,30 +2704,49 @@ Gcc_backend::global_variable(const std::string& var_name,
 
   // The GNU linker does not like dynamic variables with zero size.
   tree orig_type_tree = type_tree;
+  bool is_external = (flags & variable_is_external) != 0;
+  bool is_hidden = (flags & variable_is_hidden) != 0;
   if ((is_external || !is_hidden) && int_size_in_bytes(type_tree) == 0)
     type_tree = this->non_zero_size_type(type_tree);
 
   tree decl = build_decl(location.gcc_location(), VAR_DECL,
 			 get_identifier_from_string(var_name),
 			 type_tree);
-  if (is_external)
-    DECL_EXTERNAL(decl) = 1;
-  else
-    TREE_STATIC(decl) = 1;
-  if (!is_hidden)
+  if ((flags & variable_is_external) != 0)
     {
-      TREE_PUBLIC(decl) = 1;
-      SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
+      DECL_EXTERNAL(decl) = 1;
+      flags &=~ variable_is_external;
     }
   else
+    TREE_STATIC(decl) = 1;
+
+  if ((flags & variable_is_hidden) == 0)
+    TREE_PUBLIC(decl) = 1;
+  else
+    flags &=~ variable_is_hidden;
+
+  if ((flags & variable_address_is_taken) != 0)
     {
-      SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
+      TREE_ADDRESSABLE(decl) = 1;
+      flags &=~ variable_address_is_taken;
     }
 
+  // We take the address in Bvariable::get_tree if orig_type_tree is
+  // different from type_tree.
+  if (orig_type_tree != type_tree)
+    TREE_ADDRESSABLE(decl) = 1;
+
+  SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
+
   TREE_USED(decl) = 1;
 
-  if (in_unique_section)
-    resolve_unique_section (decl, 0, 1);
+  if ((flags & variable_in_unique_section) != 0)
+    {
+      resolve_unique_section (decl, 0, 1);
+      flags &=~ variable_in_unique_section;
+    }
+
+  gcc_assert(flags == 0);
 
   go_preserve_from_gc(decl);
 
@@ -2768,7 +2784,7 @@ Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
 Bvariable*
 Gcc_backend::local_variable(Bfunction* function, const std::string& name,
 			    Btype* btype, Bvariable* decl_var, 
-			    bool is_address_taken, Location location)
+			    unsigned int flags, Location location)
 {
   tree type_tree = btype->get_tree();
   if (type_tree == error_mark_node)
@@ -2778,13 +2794,17 @@ Gcc_backend::local_variable(Bfunction* function, const std::string& name,
 			 type_tree);
   DECL_CONTEXT(decl) = function->get_tree();
   TREE_USED(decl) = 1;
-  if (is_address_taken)
-    TREE_ADDRESSABLE(decl) = 1;
+  if ((flags & variable_address_is_taken) != 0)
+    {
+      TREE_ADDRESSABLE(decl) = 1;
+      flags &=~ variable_address_is_taken;
+    }
   if (decl_var != NULL)
     {
       DECL_HAS_VALUE_EXPR_P(decl) = 1;
       SET_DECL_VALUE_EXPR(decl, decl_var->get_decl());
     }
+  go_assert(flags == 0);
   go_preserve_from_gc(decl);
   return new Bvariable(decl);
 }
@@ -2793,7 +2813,7 @@ Gcc_backend::local_variable(Bfunction* function, const std::string& name,
 
 Bvariable*
 Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
-				Btype* btype, bool is_address_taken,
+				Btype* btype, unsigned int flags,
 				Location location)
 {
   tree type_tree = btype->get_tree();
@@ -2805,8 +2825,12 @@ Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
   DECL_CONTEXT(decl) = function->get_tree();
   DECL_ARG_TYPE(decl) = type_tree;
   TREE_USED(decl) = 1;
-  if (is_address_taken)
-    TREE_ADDRESSABLE(decl) = 1;
+  if ((flags & variable_address_is_taken) != 0)
+    {
+      TREE_ADDRESSABLE(decl) = 1;
+      flags &=~ variable_address_is_taken;
+    }
+  go_assert(flags == 0);
   go_preserve_from_gc(decl);
   return new Bvariable(decl);
 }
@@ -2815,7 +2839,8 @@ Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
 
 Bvariable*
 Gcc_backend::static_chain_variable(Bfunction* function, const std::string& name,
-				   Btype* btype, Location location)
+				   Btype* btype, unsigned int flags,
+				   Location location)
 {
   tree type_tree = btype->get_tree();
   if (type_tree == error_mark_node)
@@ -2840,6 +2865,7 @@ Gcc_backend::static_chain_variable(Bfunction* function, const std::string& name,
   gcc_assert(f->static_chain_decl == NULL);
   f->static_chain_decl = decl;
   DECL_STATIC_CHAIN(fndecl) = 1;
+  go_assert(flags == 0);
 
   go_preserve_from_gc(decl);
   return new Bvariable(decl);
@@ -2850,7 +2876,7 @@ Gcc_backend::static_chain_variable(Bfunction* function, const std::string& name,
 Bvariable*
 Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
 				Btype* btype, Bexpression* binit,
-				bool is_address_taken,
+				unsigned int flags,
 				Location location,
 				Bstatement** pstatement)
 {
@@ -2904,8 +2930,13 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
       && TREE_TYPE(init_tree) != void_type_node)
     DECL_INITIAL(var) = this->convert_tree(type_tree, init_tree, location);
 
-  if (is_address_taken)
-    TREE_ADDRESSABLE(var) = 1;
+  if ((flags & variable_address_is_taken) != 0)
+    {
+      TREE_ADDRESSABLE(var) = 1;
+      flags &=~ variable_address_is_taken;
+    }
+
+  gcc_assert(flags == 0);
 
   *pstatement = this->make_statement(build1_loc(location.gcc_location(),
                                                 DECL_EXPR,
@@ -2929,8 +2960,8 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
 Bvariable*
 Gcc_backend::implicit_variable(const std::string& name,
                                const std::string& asm_name,
-                               Btype* type, bool is_hidden, bool is_constant,
-			       bool is_common, int64_t alignment)
+                               Btype* type, unsigned int flags,
+			       int64_t alignment)
 {
   tree type_tree = type->get_tree();
   if (type_tree == error_mark_node)
@@ -2939,11 +2970,14 @@ Gcc_backend::implicit_variable(const std::string& name,
   tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
                          get_identifier_from_string(name), type_tree);
   DECL_EXTERNAL(decl) = 0;
-  TREE_PUBLIC(decl) = !is_hidden;
+  if ((flags & variable_is_hidden) != 0)
+    flags &=~ variable_is_hidden;
+  else
+    TREE_PUBLIC(decl) = 1;
   TREE_STATIC(decl) = 1;
   TREE_USED(decl) = 1;
   DECL_ARTIFICIAL(decl) = 1;
-  if (is_common)
+  if ((flags & variable_is_common) != 0)
     {
       DECL_COMMON(decl) = 1;
 
@@ -2960,11 +2994,19 @@ Gcc_backend::implicit_variable(const std::string& name,
       // mark this symbol as weak here.  We undo that below in
       // immutable_struct_set_init before calling mark_decl_one_only.
       DECL_WEAK(decl) = 1;
+
+      flags &=~ variable_is_common;
     }
-  if (is_constant)
+  if ((flags & variable_is_constant) != 0)
     {
       TREE_READONLY(decl) = 1;
       TREE_CONSTANT(decl) = 1;
+      flags &=~ variable_is_constant;
+    }
+  if ((flags & variable_address_is_taken) != 0)
+    {
+      TREE_ADDRESSABLE(decl) = 1;
+      flags &=~ variable_address_is_taken;
     }
   if (alignment != 0)
     {
@@ -2973,6 +3015,7 @@ Gcc_backend::implicit_variable(const std::string& name,
     }
   if (! asm_name.empty())
     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
+  gcc_assert(flags == 0);
 
   go_preserve_from_gc(decl);
   return new Bvariable(decl);
@@ -2983,7 +3026,7 @@ Gcc_backend::implicit_variable(const std::string& name,
 
 void
 Gcc_backend::implicit_variable_set_init(Bvariable* var, const std::string&,
-					Btype*, bool, bool, bool is_common,
+					Btype*, unsigned int flags,
 					Bexpression* init)
 {
   tree decl = var->get_decl();
@@ -2999,7 +3042,7 @@ Gcc_backend::implicit_variable_set_init(Bvariable* var, const std::string&,
 
   // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
   // See the comment where DECL_WEAK is set in implicit_variable.
-  if (is_common)
+  if ((flags & variable_is_common) != 0)
     {
       DECL_WEAK(decl) = 0;
       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
@@ -3038,8 +3081,8 @@ Gcc_backend::implicit_variable_reference(const std::string& name,
 Bvariable*
 Gcc_backend::immutable_struct(const std::string& name,
                               const std::string& asm_name,
-                              bool is_hidden,
-			      bool is_common, Btype* btype, Location location)
+			      unsigned int flags, Btype* btype,
+			      Location location)
 {
   tree type_tree = btype->get_tree();
   if (type_tree == error_mark_node)
@@ -3053,10 +3096,17 @@ Gcc_backend::immutable_struct(const std::string& name,
   TREE_READONLY(decl) = 1;
   TREE_CONSTANT(decl) = 1;
   DECL_ARTIFICIAL(decl) = 1;
-  if (!is_hidden)
+  if ((flags & variable_is_hidden) != 0)
+    flags &=~ variable_is_hidden;
+  else
     TREE_PUBLIC(decl) = 1;
   if (! asm_name.empty())
     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
+  if ((flags & variable_address_is_taken) != 0)
+    {
+      TREE_ADDRESSABLE(decl) = 1;
+      flags &=~ variable_address_is_taken;
+    }
 
   // When the initializer for one immutable_struct refers to another,
   // it needs to know the visibility of the referenced struct so that
@@ -3070,8 +3120,13 @@ Gcc_backend::immutable_struct(const std::string& name,
   // the right value if some other initializer refers to this one, we
   // mark this symbol as weak here.  We undo that below in
   // immutable_struct_set_init before calling mark_decl_one_only.
-  if (is_common)
-    DECL_WEAK(decl) = 1;
+  if ((flags & variable_is_common) != 0)
+    {
+      DECL_WEAK(decl) = 1;
+      flags &=~ variable_is_common;
+    }
+
+  gcc_assert(flags == 0);
 
   // We don't call rest_of_decl_compilation until we have the
   // initializer.
@@ -3085,7 +3140,7 @@ Gcc_backend::immutable_struct(const std::string& name,
 
 void
 Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
-				       bool, bool is_common, Btype*, Location,
+				       unsigned int flags, Btype*, Location,
 				       Bexpression* initializer)
 {
   tree decl = var->get_decl();
@@ -3097,7 +3152,7 @@ Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
 
   // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
   // See the comment where DECL_WEAK is set in immutable_struct.
-  if (is_common)
+  if ((flags & variable_is_common) != 0)
     {
       DECL_WEAK(decl) = 0;
       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 373b58c75a4..1f38c9110ba 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-38228e7a91d37588463307ec60420c8f17f1aee4
+5a801b15699cced5203af5c7339b375cd55ecbac
 
 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/backend.h b/gcc/go/gofrontend/backend.h
index c5b5d8f2054..5b6ffea0f6c 100644
--- a/gcc/go/gofrontend/backend.h
+++ b/gcc/go/gofrontend/backend.h
@@ -481,24 +481,51 @@ class Backend
   virtual Bvariable*
   error_variable() = 0;
 
+  // Bit flags to pass to the various methods that return Bvariable*.
+  // Not all flags are meaningful for all methods.
+
+  // Set if the variable's address is taken.  For a local variable
+  // this implies that the address does not escape the function, as
+  // otherwise the variable would be on the heap.
+  static const unsigned int variable_address_is_taken = 1 << 0;
+
+  // Set if the variable is defined in some other package.  Only
+  // meaningful for the global_variable method.  At most one of
+  // is_external, is_hidden, and is_common may be set.
+  static const unsigned int variable_is_external = 1 << 1;
+
+  // Set if the variable is not exported, and as such is only defined
+  // in the current package.  Only meaningful for global_variable,
+  // implicit_variable, and immutable_struct.  At most one of
+  // is_external, is_hidden, and is_common may be set.
+  static const unsigned variable_is_hidden = 1 << 2;
+
+  // Set if the variable should be treated as a common variable:
+  // multiple definitions with different sizes permitted in different
+  // object files, all merged into the largest definition at link
+  // time.  Only meaningful for implicit_variable and immutable_struct.
+  // At most one of is_external, is_hidden, and is_common may be set.
+  static const unsigned int variable_is_common = 1 << 3;
+
+  // Set if the variable should be put into a unique section if
+  // possible; this is intended to permit the linker to garbage
+  // collect the value if it is not referenced.  Only meaningful for
+  // global_variable.
+  static const unsigned int variable_in_unique_section = 1 << 4;
+
+  // Set if the variable should be treated as immutable.  Only
+  // meaningful for implicit_variable.  For example, this is set for
+  // slice initializers if the values must be copied to the heap.
+  static const unsigned int variable_is_constant = 1 << 5;
+
   // Create a global variable. NAME is the package-qualified name of
   // the variable.  ASM_NAME is the encoded identifier for the
   // variable, incorporating the package, and made safe for the
-  // assembler.  BTYPE is the type of the variable.  IS_EXTERNAL is
-  // true if the variable is defined in some other package.  IS_HIDDEN
-  // is true if the variable is not exported (name begins with a lower
-  // case letter).  IN_UNIQUE_SECTION is true if the variable should
-  // be put into a unique section if possible; this is intended to
-  // permit the linker to garbage collect the variable if it is not
-  // referenced.  LOCATION is where the variable was defined.
+  // assembler.  BTYPE is the type of the variable.  FLAGS is the bit
+  // flags defined above.  LOCATION is where the variable was defined.
   virtual Bvariable*
-  global_variable(const std::string& name,
-                  const std::string& asm_name,
-		  Btype* btype,
-		  bool is_external,
-		  bool is_hidden,
-		  bool in_unique_section,
-		  Location location) = 0;
+  global_variable(const std::string& name, const std::string& asm_name,
+		  Btype* btype, unsigned int flags, Location location) = 0;
 
   // A global variable will 1) be initialized to zero, or 2) be
   // initialized to a constant value, or 3) be initialized in the init
@@ -516,42 +543,40 @@ class Backend
   // null, gives the location at which the value of this variable may
   // be found, typically used to create an inner-scope reference to an
   // outer-scope variable, to extend the lifetime of the variable beyond
-  // the inner scope.  IS_ADDRESS_TAKEN is true if the address of this
-  // variable is taken (this implies that the address does not escape
-  // the function, as otherwise the variable would be on the heap).
+  // the inner scope.  FLAGS is the bit flags defined above.
   // LOCATION is where the variable is defined.  For each local variable
   // the frontend will call init_statement to set the initial value.
   virtual Bvariable*
   local_variable(Bfunction* function, const std::string& name, Btype* type,
-		 Bvariable* decl_var, bool is_address_taken, Location location) = 0;
+		 Bvariable* decl_var, unsigned int flags,
+		 Location location) = 0;
 
   // Create a function parameter.  This is an incoming parameter, not
   // a result parameter (result parameters are treated as local
   // variables).  The arguments are as for local_variable.
   virtual Bvariable*
   parameter_variable(Bfunction* function, const std::string& name,
-		     Btype* type, bool is_address_taken,
-		     Location location) = 0;
+		     Btype* type, unsigned int flags, Location location) = 0;
 
   // Create a static chain parameter.  This is the closure parameter.
   virtual Bvariable*
   static_chain_variable(Bfunction* function, const std::string& name,
-		        Btype* type, Location location) = 0;
+		        Btype* type, unsigned int flags,
+			Location location) = 0;
 
   // Create a temporary variable.  A temporary variable has no name,
   // just a type.  We pass in FUNCTION and BLOCK in case they are
   // needed.  If INIT is not NULL, the variable should be initialized
   // to that value.  Otherwise the initial value is irrelevant--the
   // backend does not have to explicitly initialize it to zero.
-  // ADDRESS_IS_TAKEN is true if the programs needs to take the
-  // address of this temporary variable.  LOCATION is the location of
+  // FLAGS is the bit flags defined above.  LOCATION is the location of
   // the statement or expression which requires creating the temporary
   // variable, and may not be very useful.  This function should
   // return a variable which can be referenced later and should set
   // *PSTATEMENT to a statement which initializes the variable.
   virtual Bvariable*
   temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression* init,
-		     bool address_is_taken, Location location,
+		     unsigned int flags, Location location,
 		     Bstatement** pstatement) = 0;
 
   // Create an implicit variable that is compiler-defined.  This is
@@ -566,46 +591,33 @@ class Backend
   //
   // TYPE is the type of the implicit variable.
   //
-  // IS_HIDDEN will be true if the descriptor should only be visible
-  // within the current object.
-  //
-  // IS_CONSTANT is true if the implicit variable should be treated like it is
-  // immutable.  For slice initializers, if the values must be copied to the
-  // heap, the variable IS_CONSTANT.
-  //
-  // IS_COMMON is true if the implicit variable should
-  // be treated as a common variable (multiple definitions with
-  // different sizes permitted in different object files, all merged
-  // into the largest definition at link time); this will be true for
-  // the zero value.  IS_HIDDEN and IS_COMMON will never both be true.
+  // FLAGS is the bit flags defined above.
   //
   // If ALIGNMENT is not zero, it is the desired alignment of the variable.
   virtual Bvariable*
   implicit_variable(const std::string& name, const std::string& asm_name,
-                    Btype* type, bool is_hidden, bool is_constant,
-                    bool is_common, int64_t alignment) = 0;
+                    Btype* type, unsigned int flags, int64_t alignment) = 0;
 
 
   // Set the initial value of a variable created by implicit_variable.
   // This must be called even if there is no initializer, i.e., INIT is NULL.
-  // The NAME, TYPE, IS_HIDDEN, IS_CONSTANT, and IS_COMMON parameters are
-  // the same ones passed to implicit_variable.  INIT will be a composite
-  // literal of type TYPE.  It will not contain any function calls or anything
-  // else that can not be put into a read-only data section.
-  // It may contain the address of variables created by implicit_variable.
+  // The NAME, TYPE, and FLAGS parameters are the same ones passed to
+  // implicit_variable.  INIT will be a composite literal of type
+  // TYPE.  It will not contain any function calls or anything else
+  // that can not be put into a read-only data section.  It may
+  // contain the address of variables created by implicit_variable.
   //
-  // If IS_COMMON is true, INIT will be NULL, and the
+  // If variable_is_common is set in FLAGS, INIT will be NULL, and the
   // variable should be initialized to all zeros.
   virtual void
   implicit_variable_set_init(Bvariable*, const std::string& name, Btype* type,
-			     bool is_hidden, bool is_constant, bool is_common,
-			     Bexpression* init) = 0;
+			     unsigned int flags, Bexpression* init) = 0;
 
   // Create a reference to a named implicit variable defined in some
   // other package.  This will be a variable created by a call to
   // implicit_variable with the same NAME, ASM_NAME and TYPE and with
-  // IS_COMMON passed as false.  This corresponds to an extern global
-  // variable in C.
+  // variable_is_common not set in FLAGS.  This corresponds to an
+  // extern global variable in C.
   virtual Bvariable*
   implicit_variable_reference(const std::string& name,
                               const std::string& asm_name,
@@ -622,15 +634,12 @@ class Backend
   // ASM_NAME is the encoded, assembler-friendly version of NAME, or
   // the empty string if no encoding is needed.
   //
-  // IS_HIDDEN will be true if the descriptor should only be visible
-  // within the current object.
-  //
-  // IS_COMMON is true if NAME may be defined by several packages, and
-  // the linker should merge all such definitions.  If IS_COMMON is
-  // false, NAME should be defined in only one file.  In general
-  // IS_COMMON will be true for the type descriptor of an unnamed type
-  // or a builtin type.  IS_HIDDEN and IS_COMMON will never both be
-  // true.
+  // FLAGS is the bit flags defined above.  The variable_is_common
+  // flag will be set if NAME may be defined by several packages, and
+  // the linker should merge all such definitions.  If the
+  // variable_is_common flag is not set, NAME should be defined in
+  // only one file.  In general variable_is_common will be set for the
+  // type descriptor of an unnamed type or a builtin type.
   //
   // TYPE will be a struct type; the type of the returned expression
   // must be a pointer to this struct type.
@@ -640,28 +649,26 @@ class Backend
   // address.  After calling this the frontend will call
   // immutable_struct_set_init.
   virtual Bvariable*
-  immutable_struct(const std::string& name,
-                   const std::string& asm_name,
-                   bool is_hidden, bool is_common,
-		   Btype* type, Location) = 0;
+  immutable_struct(const std::string& name, const std::string& asm_name,
+		   unsigned int flags, Btype* type, Location) = 0;
 
   // Set the initial value of a variable created by immutable_struct.
-  // The NAME, IS_HIDDEN, IS_COMMON, TYPE, and location parameters are
-  // the same ones passed to immutable_struct.  INITIALIZER will be a
-  // composite literal of type TYPE.  It will not contain any function
-  // calls or anything else that can not be put into a read-only data
-  // section.  It may contain the address of variables created by
+  // The NAME, FLAGS, TYPE, and location parameters are the same ones
+  // passed to immutable_struct.  INITIALIZER will be a composite
+  // literal of type TYPE.  It will not contain any function calls or
+  // anything else that can not be put into a read-only data section.
+  // It may contain the address of variables created by
   // immutable_struct.
   virtual void
   immutable_struct_set_init(Bvariable*, const std::string& name,
-			    bool is_hidden, bool is_common, Btype* type,
+			    unsigned int flags, Btype* type,
 			    Location, Bexpression* initializer) = 0;
 
   // Create a reference to a named immutable initialized data
   // structure defined in some other package.  This will be a
   // structure created by a call to immutable_struct with the same
-  // NAME, ASM_NAME and TYPE and with IS_COMMON passed as false.  This
-  // corresponds to an extern const global variable in C.
+  // NAME, ASM_NAME and TYPE and with variable_is_common not set in
+  // flags.  This corresponds to an extern const global variable in C.
   virtual Bvariable*
   immutable_struct_reference(const std::string& name,
                              const std::string& asm_name,
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 5409d269ebf..5d45e4baab4 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -1427,7 +1427,7 @@ Sink_expression::do_get_backend(Translate_context* context)
       Bstatement* decl;
       this->bvar_ =
 	gogo->backend()->temporary_variable(fn_ctx, context->bblock(), bt, NULL,
-					    false, loc, &decl);
+					    0, loc, &decl);
       Bexpression* var_ref =
           gogo->backend()->var_expression(this->bvar_, loc);
       var_ref = gogo->backend()->compound_expression(decl, var_ref, loc);
@@ -1724,10 +1724,12 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
       if (no->is_function() && no->func_value()->is_referenced_by_inline())
 	is_hidden = false;
 
+      unsigned int flags = 0;
+      if (is_hidden)
+	flags |= Backend::variable_is_hidden;
       bvar = context->backend()->immutable_struct(bname.name(),
 						  bname.optional_asm_name(),
-                                                  is_hidden, false,
-						  btype, bloc);
+						  flags, btype, bloc);
       Expression_list* vals = new Expression_list();
       vals->push_back(Expression::make_func_code_reference(this->fn_, bloc));
       Expression* init =
@@ -1736,8 +1738,7 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
       bcontext.set_is_const();
       Bexpression* binit = init->get_backend(&bcontext);
       context->backend()->immutable_struct_set_init(bvar, bname.name(),
-						    is_hidden, false, btype,
-						    bloc, binit);
+						    flags, btype, bloc, binit);
     }
 
   this->dvar_ = bvar;
@@ -5280,12 +5281,14 @@ Unary_expression::do_get_backend(Translate_context* context)
 	      copy_to_heap = (context->function() != NULL
                               || context->is_const());
 	    }
+	  unsigned int flags = (Backend::variable_is_hidden
+				| Backend::variable_address_is_taken);
+	  if (copy_to_heap)
+	    flags |= Backend::variable_is_constant;
 	  Bvariable* implicit =
-              gogo->backend()->implicit_variable(var_name, "", btype, true,
-						 copy_to_heap, false, 0);
+	    gogo->backend()->implicit_variable(var_name, "", btype, flags, 0);
 	  gogo->backend()->implicit_variable_set_init(implicit, var_name, btype,
-						      true, copy_to_heap, false,
-						      bexpr);
+						      flags, bexpr);
 	  bexpr = gogo->backend()->var_expression(implicit, loc);
 
 	  // If we are not copying a slice initializer to the heap,
@@ -5307,22 +5310,24 @@ Unary_expression::do_get_backend(Translate_context* context)
 	       && this->expr_->is_static_initializer())
         {
 	  std::string var_name(gogo->initializer_name());
+	  unsigned int flags = (Backend::variable_is_hidden
+				| Backend::variable_address_is_taken);
           Bvariable* decl =
-              gogo->backend()->immutable_struct(var_name, "", true, false,
-						btype, loc);
-          gogo->backend()->immutable_struct_set_init(decl, var_name, true,
-						     false, btype, loc, bexpr);
+	    gogo->backend()->immutable_struct(var_name, "", flags, btype, loc);
+          gogo->backend()->immutable_struct_set_init(decl, var_name, flags,
+						     btype, loc, bexpr);
           bexpr = gogo->backend()->var_expression(decl, loc);
         }
       else if (this->expr_->is_constant())
         {
           std::string var_name(gogo->initializer_name());
+	  unsigned int flags = (Backend::variable_is_hidden
+				| Backend::variable_is_constant
+				| Backend::variable_address_is_taken);
           Bvariable* decl =
-              gogo->backend()->implicit_variable(var_name, "", btype,
-                                                 true, true, false, 0);
+	    gogo->backend()->implicit_variable(var_name, "", btype, flags, 0);
           gogo->backend()->implicit_variable_set_init(decl, var_name, btype,
-                                                      true, true, false,
-                                                      bexpr);
+						      flags, bexpr);
           bexpr = gogo->backend()->var_expression(decl, loc);
         }
 
@@ -14888,7 +14893,9 @@ Allocation_expression::do_get_backend(Translate_context* context)
                            : gogo->backend()->zero_expression(btype));
       Bvariable* temp =
         gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
-                                            init, true, loc, &decl);
+                                            init,
+					    Backend::variable_address_is_taken,
+					    loc, &decl);
       Bexpression* ret = gogo->backend()->var_expression(temp, loc);
       ret = gogo->backend()->address_expression(ret, loc);
       ret = gogo->backend()->compound_expression(decl, ret, loc);
@@ -17238,7 +17245,9 @@ Heap_expression::do_get_backend(Translate_context* context)
   Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
   Bvariable* space_temp =
     gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
-					space, true, loc, &decl);
+					space,
+					Backend::variable_address_is_taken,
+					loc, &decl);
   Btype* expr_btype = etype->get_backend(gogo);
 
   Bexpression* bexpr = this->expr_->get_backend(context);
@@ -17259,8 +17268,9 @@ Heap_expression::do_get_backend(Translate_context* context)
       Bstatement* edecl;
       Bvariable* btemp =
 	gogo->backend()->temporary_variable(fndecl, context->bblock(),
-					    expr_btype, bexpr, true, loc,
-					    &edecl);
+					    expr_btype, bexpr,
+					    Backend::variable_address_is_taken,
+					    loc, &edecl);
       Bexpression* btempref = gogo->backend()->var_expression(btemp,
 							      loc);
       space = gogo->backend()->var_expression(space_temp, loc);
@@ -18478,10 +18488,13 @@ Interface_mtable_expression::do_get_backend(Translate_context* context)
   Bexpression* ctor =
       gogo->backend()->constructor_expression(btype, ctor_bexprs, loc);
 
-  this->bvar_ = gogo->backend()->immutable_struct(mangled_name, "", false,
-						  !is_public, btype, loc);
-  gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, false,
-                                             !is_public, btype, loc, ctor);
+  unsigned int flags = 0;
+  if (!is_public)
+    flags |= Backend::variable_is_hidden;
+  this->bvar_ = gogo->backend()->immutable_struct(mangled_name, "", flags,
+						  btype, loc);
+  gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, flags,
+					     btype, loc, ctor);
   return gogo->backend()->var_expression(this->bvar_, loc);
 }
 
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 93b54fd8c11..2872d2ed3ab 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -918,9 +918,8 @@ Gogo::build_type_descriptor_list()
 
   // Create the variable
   std::string name = this->type_descriptor_list_symbol(this->pkgpath_symbol());
-  Bvariable* bv = this->backend()->implicit_variable(name, name, bt,
-                                                     false, true, false,
-                                                     0);
+  unsigned int flags = Backend::variable_is_constant;
+  Bvariable* bv = this->backend()->implicit_variable(name, name, bt, flags, 0);
 
   // Build the initializer
   std::vector<unsigned long> indexes;
@@ -946,8 +945,7 @@ Gogo::build_type_descriptor_list()
   Bexpression* binit =
     this->backend()->constructor_expression(bt, fields, builtin_loc);
 
-  this->backend()->implicit_variable_set_init(bv, name, bt, false,
-                                              true, false, binit);
+  this->backend()->implicit_variable_set_init(bv, name, bt, flags, binit);
 }
 
 // Register the type descriptors with the runtime.  This is to help
@@ -1002,11 +1000,11 @@ Gogo::register_type_descriptors(std::vector<Bstatement*>& init_stmts,
 
   // Create a variable holding the list.
   std::string name = this->typelists_symbol();
-  Bvariable* bv = this->backend()->implicit_variable(name, name, bat,
-                                                     true, true, false,
+  unsigned int flags = (Backend::variable_is_hidden
+			| Backend::variable_is_constant);
+  Bvariable* bv = this->backend()->implicit_variable(name, name, bat, flags,
                                                      0);
-  this->backend()->implicit_variable_set_init(bv, name, bat, true, true,
-                                              false, barray);
+  this->backend()->implicit_variable_set_init(bv, name, bat, flags, barray);
 
   // Build the call in main package's init function.
   Translate_context context(this, NULL, NULL, NULL);
@@ -8062,16 +8060,24 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
 	      if (package != NULL)
 		is_hidden = false;
 
+	      unsigned int flags = 0;
+	      if (this->is_address_taken_
+		  || this->is_non_escaping_address_taken_)
+		flags |= Backend::variable_address_is_taken;
+	      if (package != NULL)
+		flags |= Backend::variable_is_external;
+	      if (is_hidden)
+		flags |= Backend::variable_is_hidden;
+	      if (this->in_unique_section_)
+		flags |= Backend::variable_in_unique_section;
+
 	      // For some reason asm_name can't be the empty string
 	      // for global_variable, so we call asm_name rather than
 	      // optional_asm_name here.  FIXME.
 
 	      bvar = backend->global_variable(bname.name(),
 					      bname.asm_name(),
-					      btype,
-					      package != NULL,
-					      is_hidden,
-					      this->in_unique_section_,
+					      btype, flags,
 					      this->location_);
 	    }
 	  else if (function == NULL)
@@ -8083,15 +8089,16 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
 	    {
 	      const std::string n = Gogo::unpack_hidden_name(name);
 	      Bfunction* bfunction = function->func_value()->get_decl();
-	      bool is_address_taken = (this->is_non_escaping_address_taken_
-				       && !this->is_in_heap());
+	      unsigned int flags = 0;
+	      if (this->is_non_escaping_address_taken_
+		  && !this->is_in_heap())
+		flags |= Backend::variable_address_is_taken;
 	      if (this->is_closure())
 		bvar = backend->static_chain_variable(bfunction, n, btype,
-						      this->location_);
+						      flags, this->location_);
 	      else if (is_parameter)
 		bvar = backend->parameter_variable(bfunction, n, btype,
-						   is_address_taken,
-						   this->location_);
+						   flags, this->location_);
 	      else
                 {
                   Bvariable* bvar_decl = NULL;
@@ -8102,8 +8109,7 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
                         ->get_backend_variable(&context);
                     }
                   bvar = backend->local_variable(bfunction, n, btype,
-                                                 bvar_decl,
-                                                 is_address_taken,
+                                                 bvar_decl, flags,
                                                  this->location_);
                 }
 	    }
@@ -8134,10 +8140,12 @@ Result_variable::get_backend_variable(Gogo* gogo, Named_object* function,
 	  Btype* btype = type->get_backend(gogo);
 	  Bfunction* bfunction = function->func_value()->get_decl();
 	  std::string n = Gogo::unpack_hidden_name(name);
-	  bool is_address_taken = (this->is_non_escaping_address_taken_
-				   && !this->is_in_heap());
+	  unsigned int flags = 0;
+	  if (this->is_non_escaping_address_taken_
+	      && !this->is_in_heap())
+	    flags |= Backend::variable_address_is_taken;
 	  this->backend_ = backend->local_variable(bfunction, n, btype,
-						   NULL, is_address_taken,
+						   NULL, flags,
 						   this->location_);
 	}
     }
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index b0660111ac8..9643d1b42b3 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -643,11 +643,13 @@ Temporary_statement::do_get_backend(Translate_context* context)
     binit = context->backend()->convert_expression(btype, binit,
                                                    this->location());
 
+  unsigned int flags = 0;
+  if (this->is_address_taken_)
+    flags |= Backend::variable_address_is_taken;
   Bstatement* statement;
   this->bvariable_ =
     context->backend()->temporary_variable(bfunction, context->bblock(),
-					   btype, binit,
-					   this->is_address_taken_,
+					   btype, binit, flags,
 					   this->location(), &statement);
   return statement;
 }
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 7d4c47f1c42..d08cbc96ea1 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -1410,10 +1410,12 @@ Type::make_type_descriptor_var(Gogo* gogo)
   // ensure that type_descriptor_pointer will work if called while
   // converting INITIALIZER.
 
+  unsigned int flags = 0;
+  if (is_common)
+    flags |= Backend::variable_is_common;
   this->type_descriptor_var_ =
     gogo->backend()->immutable_struct(bname.name(), bname.optional_asm_name(),
-				      false, is_common, initializer_btype,
-				      loc);
+				      flags, initializer_btype, loc);
   if (phash != NULL)
     *phash = this->type_descriptor_var_;
 
@@ -1422,7 +1424,7 @@ Type::make_type_descriptor_var(Gogo* gogo)
   Bexpression* binitializer = initializer->get_backend(&context);
 
   gogo->backend()->immutable_struct_set_init(this->type_descriptor_var_,
-					     bname.name(), false, is_common,
+					     bname.name(), flags,
 					     initializer_btype, loc,
 					     binitializer);
 
@@ -2714,9 +2716,13 @@ Type::make_gc_symbol_var(Gogo* gogo)
   // Since we are building the GC symbol in this package, we must create the
   // variable before converting the initializer to its backend representation
   // because the initializer may refer to the GC symbol for this type.
+  unsigned int flags = Backend::variable_is_constant;
+  if (is_common)
+    flags |= Backend::variable_is_common;
+  else
+    flags |= Backend::variable_is_hidden;
   this->gc_symbol_var_ =
-      gogo->backend()->implicit_variable(sym_name, "", sym_btype, false, true,
-					 is_common, 0);
+    gogo->backend()->implicit_variable(sym_name, "", sym_btype, flags, 0);
   if (phash != NULL)
     *phash = this->gc_symbol_var_;
 
@@ -2724,8 +2730,7 @@ Type::make_gc_symbol_var(Gogo* gogo)
   context.set_is_const();
   Bexpression* sym_binit = sym_init->get_backend(&context);
   gogo->backend()->implicit_variable_set_init(this->gc_symbol_var_, sym_name,
-					      sym_btype, false, true, is_common,
-					      sym_binit);
+					      sym_btype, flags, sym_binit);
 }
 
 // Return whether this type needs a GC program, and set *PTRDATA to
@@ -3013,11 +3018,12 @@ Type::gc_ptrmask_var(Gogo* gogo, int64_t ptrsize, int64_t ptrdata)
   Bexpression* bval = val->get_backend(&context);
 
   Btype *btype = val->type()->get_backend(gogo);
+  unsigned int flags = (Backend::variable_is_constant
+			| Backend::variable_is_common);
   Bvariable* ret = gogo->backend()->implicit_variable(sym_name, "",
-						      btype, false, true,
-						      true, 0);
-  gogo->backend()->implicit_variable_set_init(ret, sym_name, btype, false,
-					      true, true, bval);
+						      btype, flags, 0);
+  gogo->backend()->implicit_variable_set_init(ret, sym_name, btype, flags,
+					      bval);
   ins.first->second = ret;
   return ret;
 }
@@ -8145,11 +8151,12 @@ Map_type::backend_zero_value(Gogo* gogo)
   Btype* barray_type = gogo->backend()->array_type(buint8_type, blength);
 
   std::string zname = Map_type::zero_value->name();
+  unsigned int flags = Backend::variable_is_common;
   Bvariable* zvar =
-      gogo->backend()->implicit_variable(zname, "", barray_type, false, false,
-					 true, Map_type::zero_value_align);
+    gogo->backend()->implicit_variable(zname, "", barray_type, flags,
+				       Map_type::zero_value_align);
   gogo->backend()->implicit_variable_set_init(zvar, zname, barray_type,
-					      false, false, true, NULL);
+					      flags, NULL);
   return zvar;
 }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-05-24 20:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-24 20:25 [gcc r12-1022] compiler: mark global variables whose address is taken Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).