[debug-early] fix C++ mangling issues with deferred_asm_name removal
diff mbox

Message ID 54B6C9B1.2020407@redhat.com
State New
Headers show

Commit Message

Aldy Hernandez Jan. 14, 2015, 7:55 p.m. UTC
There were some -fcompare-debug regressions when I removed the 
deferred_asm_name auxiliary data structure from dwarf2out.  Jason was 
kind enough to tackle them (or at least the main one).

Apparently there was some bug in the mangling code that necessitated the 
entire deferred_asm_name vector.  I'll let Jason explain further.

With this patch I see less guality failures than mainline, so perhaps 
removing deferred_asm_name can be pushed to mainline as soon as stage1 
opens, or earlier if we feel lucky.

I will be committing this patch, as well as my deferred_asm_name removal 
patch to the branch.

Thanks.
commit 0c817fd43f95029153045b9523c1c8b49291e4a3
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Wed Jan 14 10:12:40 2015 -0800

    	cp/
    	* decl2.c (mangling_aliases): New variable.
    	(note_mangling_alias, generate_mangling_aliases): New.
    	(cp_write_global_declarations): Call generate_mangling_aliases.
    	(generate_mangling_alias): Split out from...
    	* mangle.c (mangle_decl): ...here.
    	* cp-tree.h: Declare note_mangling_alias.

Patch
diff mbox

diff --git a/gcc/ChangeLog.debug-early b/gcc/ChangeLog.debug-early
index 48d1913..f4fb4ba 100644
--- a/gcc/ChangeLog.debug-early
+++ b/gcc/ChangeLog.debug-early
@@ -1,3 +1,13 @@ 
+2015-01-14  Jason Merrill  <jason@redhat.com>
+
+	cp/
+	* decl2.c (mangling_aliases): New variable.
+	(note_mangling_alias, generate_mangling_aliases): New.
+	(cp_write_global_declarations): Call generate_mangling_aliases.
+	(generate_mangling_alias): Split out from...
+	* mangle.c (mangle_decl): ...here.
+	* cp-tree.h: Declare note_mangling_alias.
+
 2015-01-06  Aldy Hernandez  <aldyh@redhat.com>
 
 	* dwarf2out.c: Remove deferred_asm_name.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 98f2e20..5fa96cb 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5431,6 +5431,7 @@  extern tree finish_case_label			(location_t, tree, tree);
 extern tree cxx_maybe_build_cleanup		(tree, tsubst_flags_t);
 
 /* in decl2.c */
+extern void note_mangling_alias			(tree, tree);
 extern bool check_java_method			(tree);
 extern tree build_memfn_type			(tree, tree, cp_cv_quals, cp_ref_qualifier);
 extern tree build_pointer_ptrmemfn_type	(tree);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index abcaeac..691688b 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -114,6 +114,10 @@  static GTY(()) vec<tree, va_gc> *deferred_fns;
    sure are defined.  */
 static GTY(()) vec<tree, va_gc> *no_linkage_decls;
 
+/* A vector of alternating decls and identifiers, where the latter
+   is to be an alias for the former if the former is defined.  */
+static GTY(()) vec<tree, va_gc> *mangling_aliases;
+
 /* Nonzero if we're done parsing and into end-of-file activities.  */
 
 int at_eof;
@@ -4253,6 +4257,66 @@  handle_tls_init (void)
   expand_or_defer_fn (finish_function (0));
 }
 
+/* We're at the end of compilation, so generate any mangling aliases that
+   we've been saving up, if DECL is going to be output and ID2 isn't
+   already taken by another declaration.  */
+
+static void
+generate_mangling_alias (tree decl, tree id2)
+{
+  /* If there's a declaration already using this mangled name,
+     don't create a compatibility alias that conflicts.  */
+  if (IDENTIFIER_GLOBAL_VALUE (id2))
+    return;
+
+  struct cgraph_node *n = NULL;
+  if (TREE_CODE (decl) == FUNCTION_DECL
+      && !(n = cgraph_node::get (decl)))
+    /* Don't create an alias to an unreferenced function.  */
+    return;
+
+  tree alias = make_alias_for (decl, id2);
+  SET_IDENTIFIER_GLOBAL_VALUE (id2, alias);
+  DECL_IGNORED_P (alias) = 1;
+  TREE_PUBLIC (alias) = TREE_PUBLIC (decl);
+  DECL_VISIBILITY (alias) = DECL_VISIBILITY (decl);
+  if (vague_linkage_p (decl))
+    DECL_WEAK (alias) = 1;
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+    n->create_same_body_alias (alias, decl);
+  else
+    varpool_node::create_extra_name_alias (alias, decl);
+}
+
+/* Note that we might want to emit an alias with the symbol ID2 for DECL at
+   the end of translation, for compatibility across bugs in the mangling
+   implementation.  */
+
+void
+note_mangling_alias (tree decl, tree id2)
+{
+#ifdef ASM_OUTPUT_DEF
+  if (at_eof)
+    generate_mangling_alias (decl, id2);
+  else
+    {
+      vec_safe_push (mangling_aliases, decl);
+      vec_safe_push (mangling_aliases, id2);
+    }
+#endif
+}
+
+static void
+generate_mangling_aliases ()
+{
+  while (!vec_safe_is_empty (mangling_aliases))
+    {
+      tree id2 = mangling_aliases->pop();
+      tree decl = mangling_aliases->pop();
+      generate_mangling_alias (decl, id2);
+    }
+}
+
 /* The entire file is now complete.  If requested, dump everything
    to a file.  */
 
@@ -4593,6 +4657,8 @@  c_parse_final_cleanups (void)
     }
   while (reconsider);
 
+  generate_mangling_aliases ();
+
   /* All used inline functions must have a definition at this point.  */
   FOR_EACH_VEC_SAFE_ELT (deferred_fns, i, decl)
     {
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 71a6e3b..3da81b3 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -3512,30 +3512,7 @@  mangle_decl (const tree decl)
 		     flag_abi_compat_version, id2);
 	}
 
-#ifdef ASM_OUTPUT_DEF
-      /* If there's a declaration already using this mangled name,
-	 don't create a compatibility alias that conflicts.  */
-      if (IDENTIFIER_GLOBAL_VALUE (id2))
-	return;
-
-      struct cgraph_node *n = NULL;
-      if (TREE_CODE (decl) == FUNCTION_DECL
-	  && !(n = cgraph_node::get (decl)))
-	/* Don't create an alias to an unreferenced function.  */
-	return;
-
-      tree alias = make_alias_for (decl, id2);
-      SET_IDENTIFIER_GLOBAL_VALUE (id2, alias);
-      DECL_IGNORED_P (alias) = 1;
-      TREE_PUBLIC (alias) = TREE_PUBLIC (decl);
-      DECL_VISIBILITY (alias) = DECL_VISIBILITY (decl);
-      if (vague_linkage_p (decl))
-	DECL_WEAK (alias) = 1;
-      if (TREE_CODE (decl) == FUNCTION_DECL)
-	n->create_same_body_alias (alias, decl);
-      else
-	varpool_node::create_extra_name_alias (alias, decl);
-#endif
+      note_mangling_alias (decl, id2);
     }
 }