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]

[5 PATCH] Fix ICE with mangling aliases (PR c++/67354)


Hi!

On Thu, Nov 19, 2015 at 03:04:35PM -0500, Jason Merrill wrote:
> On 11/19/2015 07:40 AM, Jakub Jelinek wrote:
> >@@ -4502,6 +4509,7 @@ c_parse_final_cleanups (void)
> >
> >    locus_at_end_of_parsing = input_location;
> >    at_eof = 1;
> >+  defer_mangling_aliases = false;
> 
> Let's clear this in generate_mangling_aliases rather than here.  OK with
> that change.

Unfortunately, the GCC 5.3 backport of this is larger, because it relies
on the deferring of the mangling aliases that has been added during the
early debug efforts.  Still, it looks to me small enough.
Bootstrapped/regtested on GCC 5 branch on x86_64-linux and i686-linux, ok
for branch?

2015-11-23  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2015-11-20  Jakub Jelinek  <jakub@redhat.com>

	PR c++/67354
	* cp-tree.h (defer_mangling_aliases): Declare.
	(generate_mangling_aliases): New prototype.
	* decl2.c (defer_mangling_aliases): New variable.
	(note_mangling_alias): Use !defer_mangling_aliases
	instead of at_eof.
	(generate_mangling_aliases): No longer static. Clear
	defer_mangling_aliases.
	* optimize.c (maybe_thunk_body): Defer emitting mangling aliases
	if !defer_mangling_aliases until the fns are put into the same
	comdat group.

	* g++.dg/abi/mangle67.C: New test.

	2015-05-09  Aldy Hernandez  <aldyh@redhat.com>

	PR bootstrap/66085
	* decl2.c (note_mangling_alias): Declare arguments as unused.

	2015-05-08  Jason Merrill  <jason@redhat.com>

	* 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.

--- gcc/cp/cp-tree.h.jj	2015-11-20 10:12:02.917358200 +0100
+++ gcc/cp/cp-tree.h	2015-11-23 10:42:12.707937270 +0100
@@ -4606,6 +4606,11 @@ extern GTY(()) vec<tree, va_gc> *local_c
 
 extern int at_eof;
 
+/* True if note_mangling_alias should enqueue mangling aliases for
+   later generation, rather than emitting them right away.  */
+
+extern bool defer_mangling_aliases;
+
 /* A list of namespace-scope objects which have constructors or
    destructors which reside in the global scope.  The decl is stored
    in the TREE_VALUE slot and the initializer is stored in the
@@ -5453,6 +5458,8 @@ extern tree finish_case_label			(locatio
 extern tree cxx_maybe_build_cleanup		(tree, tsubst_flags_t);
 
 /* in decl2.c */
+extern void note_mangling_alias			(tree, tree);
+extern void generate_mangling_aliases		(void);
 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);
--- gcc/cp/mangle.c.jj	2015-09-04 20:33:01.456531377 +0200
+++ gcc/cp/mangle.c	2015-11-23 10:37:30.668926382 +0100
@@ -3584,30 +3584,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);
     }
 }
 
--- gcc/cp/optimize.c.jj	2015-11-20 10:12:02.941357861 +0100
+++ gcc/cp/optimize.c	2015-11-23 10:42:12.709937242 +0100
@@ -294,7 +294,11 @@ maybe_thunk_body (tree fn, bool force)
     }
   else if (HAVE_COMDAT_GROUP)
     {
+      /* At eof, defer creation of mangling aliases temporarily.  */
+      bool save_defer_mangling_aliases = defer_mangling_aliases;
+      defer_mangling_aliases = true;
       tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
+      defer_mangling_aliases = save_defer_mangling_aliases;
       cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
       cgraph_node::get_create (fns[1])->add_to_same_comdat_group
 	(cgraph_node::get_create (fns[0]));
@@ -305,6 +309,9 @@ maybe_thunk_body (tree fn, bool force)
 	   virtual, it goes into the same comdat group as well.  */
 	cgraph_node::get_create (fns[2])->add_to_same_comdat_group
 	  (symtab_node::get (fns[0]));
+      /* Emit them now that the thunks are same comdat group aliases.  */
+      if (!save_defer_mangling_aliases)
+	generate_mangling_aliases ();
       TREE_PUBLIC (fn) = false;
       DECL_EXTERNAL (fn) = false;
       DECL_INTERFACE_KNOWN (fn) = true;
--- gcc/cp/decl2.c.jj	2015-11-20 10:12:02.926358073 +0100
+++ gcc/cp/decl2.c	2015-11-23 10:42:12.709937242 +0100
@@ -118,9 +118,18 @@ static GTY(()) vec<tree, va_gc> *deferre
    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;
+
+/* True if note_mangling_alias should enqueue mangling aliases for
+   later generation, rather than emitting them right away.  */
+
+bool defer_mangling_aliases = true;
 
 
 /* Return a member function type (a METHOD_TYPE), given FNTYPE (a
@@ -4327,6 +4336,69 @@ 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 ATTRIBUTE_UNUSED, tree id2 ATTRIBUTE_UNUSED)
+{
+#ifdef ASM_OUTPUT_DEF
+  if (!defer_mangling_aliases)
+    generate_mangling_alias (decl, id2);
+  else
+    {
+      vec_safe_push (mangling_aliases, decl);
+      vec_safe_push (mangling_aliases, id2);
+    }
+#endif
+}
+
+/* Emit all mangling aliases that were deferred up to this point.  */
+
+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);
+    }
+  defer_mangling_aliases = false;
+}
+
 /* The entire file is now complete.  If requested, dump everything
    to a file.  */
 
@@ -4688,6 +4760,8 @@ cp_write_global_declarations (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)
     {
--- gcc/testsuite/g++.dg/abi/mangle67.C.jj	2015-11-23 10:42:21.936807654 +0100
+++ gcc/testsuite/g++.dg/abi/mangle67.C	2015-11-23 10:42:12.710937228 +0100
@@ -0,0 +1,21 @@
+// PR c++/67354
+// { dg-do compile { target c++11 } }
+// { dg-options "-fabi-version=5 -Os" }
+
+class A
+{
+};
+
+template <typename T>
+void
+foo ()
+{
+  T ();
+}
+
+struct B : virtual A
+{
+  template <typename...> B () {}
+};
+
+auto f = foo<B>;


	Jakub


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