This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix libgo build


Hi,
libgo currently does not build because of duplicated symbols. This is because of
confusion in the output machinery, where comdat local is output as a global
symbol.  This is because of confusing use of DECL_ONE_ONLY. This bug seems to be
there since introduction of comdat locals in gcc 4.9, but it was not harmful, because
all symbols C++ produce have unique name.


Instead of one-liner to special case comdat locals in elfos.h, it seems better
to make DECL_ONE_ONLY more meaningful and make it return true only on real comdats,
not on comdat locals.
This patch does that and revisits its use in the back-end.  Basically all tests
that care about the fact if function should go into special section needs to
be DECL_COMDAT_GROUP (decl), because we care if function is in comdat group.
All tests that care about special semantic of comdats needs to be DECL_ONE_ONLY.

For those who are interested, the oneliner is:

Index: config/elfos.h
===================================================================
--- config/elfos.h	(revision 210623)
+++ config/elfos.h	(working copy)
@@ -303,6 +303,7 @@
 	 RTLD_LOCAL.  Don't use gnu_unique_object for typeinfo,		\
 	 vtables and other read-only artificial decls.  */		\
       if (USE_GNU_UNIQUE_OBJECT && DECL_ONE_ONLY (DECL)			\
+	  && TREE_PUBLIC (DECL)						\
 	  && (!DECL_ARTIFICIAL (DECL) || !TREE_READONLY (DECL)))	\
 	ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "gnu_unique_object");	\
       else								\

Bootstrapped/regtested x86_64-linux, I will give it some further testing and commit
at afternoon if there are no complains.

Honza

	PR go/61232
	* tree.h (DECL_ONE_ONLY): Return true only for externally visible
	symbols.
	* except.c (switch_to_exception_section, resolve_unique_section,
	get_named_text_section, default_function_rodata_section, 
	align_variable, get_block_for_decl, default_section_type_flags):
	Use DECL_COMDAT_GROUP instead of DECL_ONE_ONLY.
	* symtab.c (symtab_add_to_same_comdat_group,
	symtab_make_decl_local, fixup_same_cpp_alias_visibility,
	symtab_nonoverwritable_alias, symtab_get_symbol_partitioning_class):
	Likewise.
	* cgraphclones.c (cgraph_create_virtual_clone): Likewise.
	* bb-reorder.c (pass_partition_blocks::gate): Likewise.
	* config/c6x/c6x.c (c6x_elf_unique_section): Likewise.
	(c6x_function_in_section_p): Likewise.
	* config/darwin.c (machopic_select_section): Likewise.
	* config/arm/arm.c (arm_function_in_section_p): Likewise.
	* config/mips/mips.c (mips_function_rodata_section): Likewise.
	* config/mep/mep.c (mep_select_section): LIkewise.
	* config/i386/i386.c (x86_64_elf_unique_section): Likewise.

Index: tree.h
===================================================================
--- tree.h	(revision 210521)
+++ tree.h	(working copy)
@@ -2327,7 +2327,8 @@ extern void decl_value_expr_insert (tree
 
 /* Used in TREE_PUBLIC decls to indicate that copies of this DECL in
    multiple translation units should be merged.  */
-#define DECL_ONE_ONLY(NODE) (DECL_COMDAT_GROUP (NODE) != NULL_TREE)
+#define DECL_ONE_ONLY(NODE) (DECL_COMDAT_GROUP (NODE) != NULL_TREE \
+			     && (TREE_PUBLIC (NODE) || DECL_EXTERNAL (NODE)))
 
 /* The name of the object as the assembler will see it (but before any
    translations made by ASM_OUTPUT_LABELREF).  Often this is the same
Index: except.c
===================================================================
--- except.c	(revision 210521)
+++ except.c	(working copy)
@@ -2854,12 +2854,12 @@ switch_to_exception_section (const char
 
 #ifdef HAVE_LD_EH_GC_SECTIONS
 	  if (flag_function_sections
-	      || (DECL_ONE_ONLY (current_function_decl) && HAVE_COMDAT_GROUP))
+	      || (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP))
 	    {
 	      char *section_name = XNEWVEC (char, strlen (fnname) + 32);
 	      /* The EH table must match the code section, so only mark
 		 it linkonce if we have COMDAT groups to tie them together.  */
-	      if (DECL_ONE_ONLY (current_function_decl) && HAVE_COMDAT_GROUP)
+	      if (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP)
 		flags |= SECTION_LINKONCE;
 	      sprintf (section_name, ".gcc_except_table.%s", fnname);
 	      s = get_section (section_name, flags, current_function_decl);
Index: varasm.c
===================================================================
--- varasm.c	(revision 210521)
+++ varasm.c	(working copy)
@@ -428,7 +428,7 @@ resolve_unique_section (tree decl, int r
   if (DECL_SECTION_NAME (decl) == NULL_TREE
       && targetm_common.have_named_sections
       && (flag_function_or_data_sections
-	  || DECL_ONE_ONLY (decl)))
+	  || DECL_COMDAT_GROUP (decl)))
     {
       targetm.asm_out.unique_section (decl, reloc);
       DECL_HAS_IMPLICIT_SECTION_NAME_P (decl) = true;
@@ -517,7 +517,7 @@ get_named_text_section (tree decl,
 
 	  /* Do not try to split gnu_linkonce functions.  This gets somewhat
 	     slipperly.  */
-	  if (DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP)
+	  if (DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP)
 	    return NULL;
 	  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
 	  name = targetm.strip_name_encoding (name);
@@ -687,7 +687,7 @@ default_function_rodata_section (tree de
     {
       const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
 
-      if (DECL_ONE_ONLY (decl) && HAVE_COMDAT_GROUP)
+      if (DECL_COMDAT_GROUP (decl) && HAVE_COMDAT_GROUP)
         {
 	  const char *dot;
 	  size_t len;
@@ -704,7 +704,7 @@ default_function_rodata_section (tree de
 	  return get_section (rname, SECTION_LINKONCE, decl);
 	}
       /* For .gnu.linkonce.t.foo we want to use .gnu.linkonce.r.foo.  */
-      else if (DECL_ONE_ONLY (decl)
+      else if (DECL_COMDAT_GROUP (decl)
 	       && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
 	{
 	  size_t len = strlen (name) + 1;
@@ -996,7 +996,8 @@ align_variable (tree decl, bool dont_out
 	 and for code accessing the variable as guaranteed alignment, we
 	 can only increase the alignment if it is a performance optimization
 	 if the references to it must bind to the current definition.  */
-      if (decl_binds_to_current_def_p (decl))
+      if (decl_binds_to_current_def_p (decl)
+	  && !DECL_VIRTUAL_P (decl))
 	{
 #ifdef DATA_ALIGNMENT
 	  unsigned int data_align = DATA_ALIGNMENT (TREE_TYPE (decl), align);
@@ -1142,7 +1143,7 @@ get_block_for_decl (tree decl)
 
       /* There's no point using object blocks for something that is
 	 isolated by definition.  */
-      if (DECL_ONE_ONLY (decl))
+      if (DECL_COMDAT_GROUP (decl))
 	return NULL;
     }
 
@@ -6076,7 +6077,7 @@ default_section_type_flags (tree decl, c
 	flags |= SECTION_RELRO;
     }
 
-  if (decl && DECL_P (decl) && DECL_ONE_ONLY (decl))
+  if (decl && DECL_P (decl) && DECL_COMDAT_GROUP (decl))
     flags |= SECTION_LINKONCE;
 
   if (strcmp (name, ".vtable_map_vars") == 0)
Index: symtab.c
===================================================================
--- symtab.c	(revision 210598)
+++ symtab.c	(working copy)
@@ -513,7 +513,7 @@ void
 symtab_add_to_same_comdat_group (symtab_node *new_node,
 				 symtab_node *old_node)
 {
-  gcc_assert (DECL_ONE_ONLY (old_node->decl));
+  gcc_assert (DECL_COMDAT_GROUP (old_node->decl));
   gcc_assert (!new_node->same_comdat_group);
   gcc_assert (new_node != old_node);
 
@@ -832,9 +832,9 @@ verify_symtab_base (symtab_node *node)
     {
       symtab_node *n = node->same_comdat_group;
 
-      if (!DECL_ONE_ONLY (n->decl))
+      if (!DECL_COMDAT_GROUP (n->decl))
 	{
-	  error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
+	  error ("node is in same_comdat_group list but has no DECL_COMDAT_GROUP");
 	  error_found = true;
 	}
       if (DECL_COMDAT_GROUP (n->decl) != DECL_COMDAT_GROUP (node->same_comdat_group->decl))
@@ -958,7 +958,7 @@ symtab_make_decl_local (tree decl)
     DECL_COMMON (decl) = 0;
   else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
 
-  if (DECL_ONE_ONLY (decl) || DECL_COMDAT (decl))
+  if (DECL_COMDAT_GROUP (decl) || DECL_COMDAT (decl))
     {
       DECL_SECTION_NAME (decl) = 0;
       DECL_COMDAT (decl) = 0;
@@ -1101,7 +1101,7 @@ fixup_same_cpp_alias_visibility (symtab_
       DECL_COMDAT (node->decl) = DECL_COMDAT (target->decl);
       DECL_COMDAT_GROUP (node->decl)
 	 = DECL_COMDAT_GROUP (target->decl);
-      if (DECL_ONE_ONLY (target->decl)
+      if (DECL_COMDAT_GROUP (target->decl)
 	  && !node->same_comdat_group)
 	symtab_add_to_same_comdat_group (node, target);
     }
@@ -1231,7 +1231,7 @@ symtab_nonoverwritable_alias (symtab_nod
 
   /* Update the properties.  */
   DECL_EXTERNAL (new_decl) = 0;
-  if (DECL_ONE_ONLY (node->decl))
+  if (DECL_COMDAT_GROUP (node->decl))
     DECL_SECTION_NAME (new_decl) = NULL;
   DECL_COMDAT_GROUP (new_decl) = 0;
   TREE_PUBLIC (new_decl) = 0;
@@ -1328,8 +1328,7 @@ symtab_get_symbol_partitioning_class (sy
     return SYMBOL_EXTERNAL;
 
   /* Linker discardable symbols are duplicated to every use unless they are
-     keyed.
-     Keyed symbols or those.  */
+     keyed.  */
   if (DECL_ONE_ONLY (node->decl)
       && !node->force_output
       && !node->forced_by_abi
Index: cgraphclones.c
===================================================================
--- cgraphclones.c	(revision 210521)
+++ cgraphclones.c	(working copy)
@@ -558,7 +558,7 @@ cgraph_create_virtual_clone (struct cgra
      that is not weak also.
      ??? We cannot use COMDAT linkage because there is no
      ABI support for this.  */
-  if (DECL_ONE_ONLY (old_decl))
+  if (DECL_COMDAT_GROUP (old_decl))
     DECL_SECTION_NAME (new_node->decl) = NULL;
   set_new_clone_decl_and_node_flags (new_node);
   new_node->clone.tree_map = tree_map;
Index: bb-reorder.c
===================================================================
--- bb-reorder.c	(revision 210521)
+++ bb-reorder.c	(working copy)
@@ -2667,7 +2667,7 @@ pass_partition_blocks::gate (function *f
 	  /* See gate_handle_reorder_blocks.  We should not partition if
 	     we are going to omit the reordering.  */
 	  && optimize_function_for_speed_p (fun)
-	  && !DECL_ONE_ONLY (current_function_decl)
+	  && !DECL_COMDAT_GROUP (current_function_decl)
 	  && !user_defined_section_attribute);
 }
 
Index: config/c6x/c6x.c
===================================================================
--- config/c6x/c6x.c	(revision 210521)
+++ config/c6x/c6x.c	(working copy)
@@ -985,7 +985,7 @@ c6x_elf_unique_section (tree decl, int r
 {
   const char *prefix = NULL;
   /* We only need to use .gnu.linkonce if we don't have COMDAT groups.  */
-  bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP;
+  bool one_only = DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP;
 
   if (c6x_in_small_data_p (decl))
     {
@@ -1202,7 +1202,7 @@ c6x_function_in_section_p (tree decl, se
   if (!DECL_SECTION_NAME (decl))
     {
       /* Make sure that we will not create a unique section for DECL.  */
-      if (flag_function_sections || DECL_ONE_ONLY (decl))
+      if (flag_function_sections || DECL_COMDAT_GROUP (decl))
 	return false;
     }
 
Index: config/darwin.c
===================================================================
--- config/darwin.c	(revision 210521)
+++ config/darwin.c	(working copy)
@@ -1521,7 +1521,7 @@ machopic_select_section (tree decl,
 
   one = DECL_P (decl) 
 	&& TREE_CODE (decl) == VAR_DECL 
-	&& DECL_ONE_ONLY (decl);
+	&& DECL_COMDAT_GROUP (decl);
 
   ro = TREE_READONLY (decl) || TREE_CONSTANT (decl) ;
 
Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c	(revision 210521)
+++ config/arm/arm.c	(working copy)
@@ -6154,7 +6154,7 @@ arm_function_in_section_p (tree decl, se
   if (!DECL_SECTION_NAME (decl))
     {
       /* Make sure that we will not create a unique section for DECL.  */
-      if (flag_function_sections || DECL_ONE_ONLY (decl))
+      if (flag_function_sections || DECL_COMDAT_GROUP (decl))
 	return false;
     }
 
Index: config/mips/mips.c
===================================================================
--- config/mips/mips.c	(revision 210521)
+++ config/mips/mips.c	(working copy)
@@ -8469,7 +8469,7 @@ mips_function_rodata_section (tree decl)
   if (decl && DECL_SECTION_NAME (decl))
     {
       const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
-      if (DECL_ONE_ONLY (decl) && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
+      if (DECL_COMDAT_GROUP (decl) && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
 	{
 	  char *rname = ASTRDUP (name);
 	  rname[14] = 'd';
Index: config/mep/mep.c
===================================================================
--- config/mep/mep.c	(revision 210521)
+++ config/mep/mep.c	(working copy)
@@ -4532,7 +4532,7 @@ mep_select_section (tree decl, int reloc
       else
 	encoding = 0;
 
-      if (flag_function_sections || DECL_ONE_ONLY (decl))
+      if (flag_function_sections || DECL_COMDAT_GROUP (decl))
 	mep_unique_section (decl, 0);
       else if (lookup_attribute ("vliw", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
 	{
@@ -4651,7 +4651,7 @@ mep_unique_section (tree decl, int reloc
       name += 3;
     }
 
-  prefix = prefixes[sec][DECL_ONE_ONLY(decl)];
+  prefix = prefixes[sec][DECL_COMDAT_GROUP(decl) != NULL];
   len    = strlen (name) + strlen (prefix);
   string = (char *) alloca (len + 1);
 
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 210521)
+++ config/i386/i386.c	(working copy)
@@ -5147,7 +5147,7 @@ x86_64_elf_unique_section (tree decl, in
     {
       const char *prefix = NULL;
       /* We only need to use .gnu.linkonce if we don't have COMDAT groups.  */
-      bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP;
+      bool one_only = DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP;
 
       switch (categorize_decl_for_section (decl, reloc))
 	{


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]