On Wed, Nov 18, 2015 at 04:22:21PM -0500, Jason Merrill wrote: > 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.
Here it is. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/5.3? 2015-11-19 Jakub Jelinek <ja...@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. (c_parse_final_cleanups): 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. --- gcc/cp/cp-tree.h.jj 2015-11-18 11:19:20.956770209 +0100 +++ gcc/cp/cp-tree.h 2015-11-19 09:58:00.355009161 +0100 @@ -4842,6 +4842,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 @@ -5768,6 +5773,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-18 11:19:12.866884363 +0100 +++ gcc/cp/decl2.c 2015-11-19 10:12:24.423695746 +0100 @@ -102,6 +102,11 @@ static GTY(()) vec<tree, va_gc> *manglin /* 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 @@ -4389,7 +4394,7 @@ void note_mangling_alias (tree decl ATTRIBUTE_UNUSED, tree id2 ATTRIBUTE_UNUSED) { #ifdef ASM_OUTPUT_DEF - if (at_eof) + if (!defer_mangling_aliases) generate_mangling_alias (decl, id2); else { @@ -4399,7 +4404,9 @@ note_mangling_alias (tree decl ATTRIBUTE #endif } -static void +/* Emit all mangling aliases that were deferred up to this point. */ + +void generate_mangling_aliases () { while (!vec_safe_is_empty (mangling_aliases)) @@ -4502,6 +4509,7 @@ c_parse_final_cleanups (void) locus_at_end_of_parsing = input_location; at_eof = 1; + defer_mangling_aliases = false; /* Bad parse errors. Just forget about it. */ if (! global_bindings_p () || current_class_type --- gcc/cp/optimize.c.jj 2015-11-18 11:19:12.935883389 +0100 +++ gcc/cp/optimize.c 2015-11-19 10:12:24.423695746 +0100 @@ -270,7 +270,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])); @@ -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_defer_mangling_aliases) + 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-19 09:54:51.644701162 +0100 +++ gcc/testsuite/g++.dg/abi/mangle67.C 2015-11-19 09:54:51.644701162 +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