diff mbox

Fix ICE with mangling aliases (PR c++/67354)

Message ID 20151118085216.GJ5675@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 18, 2015, 8:52 a.m. UTC
Hi!

This is an attempt to fix an ICE on the following testcase.
Normally (when !at_eof), note_mangling_alias just queues up the mangling
aliases in a vector, but when maybe_thunk_body is called at_eof,
it calls cdtor_comdat_group which mangles first the names of both the
fns to determine the name of the comdat group, and as it is at_eof,
it emits the mangling aliases right away.  That means the base ctor is
put into one same_comdat_group (together with its mangling alias),
and comp ctor into a different same_comdat_group.  Then a few lines later
we want to put the base ctor as same body alias with the comp ctor, but ICE,
because the two are already having non-NULL same_comdat_group.
The patch in this case temporarily queues up the mangling aliases in the
vector and only after putting the two ctors into the same comdat group
adds the mangling aliases.
If changing at_eof for this is too big hack, perhaps we could have a
different bool just to affect the mangling aliases (and set it to true
in generate_mangling_aliases or so).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/5.3?

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

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

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


	Jakub

Comments

Jason Merrill Nov. 18, 2015, 9:22 p.m. UTC | #1
On 11/18/2015 03:52 AM, Jakub Jelinek wrote:
> If changing at_eof for this is too big hack, perhaps we could have a
> different bool just to affect the mangling aliases (and set it to true
> in generate_mangling_aliases or so).

Let's do that.

Jason
diff mbox

Patch

--- gcc/cp/cp-tree.h.jj	2015-11-14 19:35:53.000000000 +0100
+++ gcc/cp/cp-tree.h	2015-11-16 15:58:44.143844060 +0100
@@ -5772,6 +5772,7 @@  extern tree cxx_maybe_build_cleanup		(tr
 
 /* 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/decl2.c.jj	2015-11-14 19:35:53.000000000 +0100
+++ gcc/cp/decl2.c	2015-11-16 15:58:09.944330046 +0100
@@ -4399,7 +4399,7 @@  note_mangling_alias (tree decl ATTRIBUTE
 #endif
 }
 
-static void
+void
 generate_mangling_aliases ()
 {
   while (!vec_safe_is_empty (mangling_aliases))
--- gcc/cp/optimize.c.jj	2015-11-14 19:35:53.000000000 +0100
+++ gcc/cp/optimize.c	2015-11-16 16:01:56.467111088 +0100
@@ -270,7 +270,11 @@  maybe_thunk_body (tree fn, bool force)
     }
   else if (HAVE_COMDAT_GROUP)
     {
+      /* Avoid creating mangling aliases if at_eof.  */
+      int save_at_eof = at_eof;
+      at_eof = 0;
       tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
+      at_eof = save_at_eof;
       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]));
@@ -281,6 +285,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_at_eof)
+	generate_mangling_aliases ();
       TREE_PUBLIC (fn) = false;
       DECL_EXTERNAL (fn) = false;
       DECL_INTERFACE_KNOWN (fn) = true;
--- gcc/testsuite/g++.dg/abi/mangle67.C.jj	2015-11-16 16:07:05.614620070 +0100
+++ gcc/testsuite/g++.dg/abi/mangle67.C	2015-11-16 16:06:35.000000000 +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>;