From b419102c126ef6fa1b80566bbe9cb299ef860432 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 4 Oct 2017 16:55:54 +0000 Subject: [PATCH] [C++ PATCH] Move mangling alias out of :: https://gcc.gnu.org/ml/gcc-patches/2017-10/msg00199.html gcc/cp/ Move mangling aliases out of global namespace. * cp-tree.h (record_mangling): New. (maybe_remove_implicit_alias): Delete. * decl2.c (mangled_decls): New hash map. (generate_mangling_alias): Reimplement using mangled_decls. (record_mangling): New. * mangle.c (decl_implicit_alias_p, maybe_remove_implicit_alias): Delete. (mangle_decl): Use record_mangling. * name-lookup.c (supplement_binding_1): Remove maybe_remove_implicit_alias check. * call.c (convert_arg_to_ellipsis): Correct comment about passing by reference. gcc/testsuite/ * g++.dg/abi/mangle41.C: Adjust diagnostics. libcc1/ * libcp1plugin.cc (supplement_binding): Don't use maybe_remove_implicit_alias. From-SVN: r253421 --- gcc/cp/ChangeLog | 14 ++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/decl2.c | 75 +++++++++++++++++++++++++---- gcc/cp/mangle.c | 52 +------------------- gcc/cp/name-lookup.c | 6 --- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/g++.dg/abi/mangle41.C | 4 +- libcc1/ChangeLog | 5 ++ libcc1/libcp1plugin.cc | 6 --- 9 files changed, 93 insertions(+), 75 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 18e4b9997b6..01b8c4d6da6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2017-10-04 Nathan Sidwell + + Move mangling aliases out of global namespace. + * cp-tree.h (record_mangling): New. + (maybe_remove_implicit_alias): Delete. + * decl2.c (mangled_decls): New hash map. + (generate_mangling_alias): Reimplement using mangled_decls. + (record_mangling): New. + * mangle.c (decl_implicit_alias_p, + maybe_remove_implicit_alias): Delete. + (mangle_decl): Use record_mangling. + * name-lookup.c (supplement_binding_1): Remove + maybe_remove_implicit_alias check. + 2017-10-04 Jakub Jelinek PR c++/82373 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a21c9485393..82ebc2831c5 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6142,6 +6142,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 record_mangling (tree, bool); extern void note_mangling_alias (tree, tree); extern void generate_mangling_aliases (void); extern tree build_memfn_type (tree, tree, cp_cv_quals, cp_ref_qualifier); @@ -7154,7 +7155,6 @@ extern tree add_exception_specifier (tree, tree, int); extern tree merge_exception_specifiers (tree, tree); /* in mangle.c */ -extern bool maybe_remove_implicit_alias (tree); extern void init_mangle (void); extern void mangle_decl (tree); extern const char *mangle_type_string (tree); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index eb9c6a59e04..354d503da6d 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -102,6 +102,10 @@ static GTY(()) vec *no_linkage_decls; is to be an alias for the former if the former is defined. */ static GTY(()) vec *mangling_aliases; +/* A hash table of mangled names to decls. Used to figure out if we + need compatibility aliases. */ +static GTY(()) hash_map *mangled_decls; + /* Nonzero if we're done parsing and into end-of-file activities. */ int at_eof; @@ -4290,25 +4294,34 @@ handle_tls_init (void) static void generate_mangling_alias (tree decl, tree id2) { + struct cgraph_node *n = NULL; + + if (TREE_CODE (decl) == FUNCTION_DECL) + { + n = cgraph_node::get (decl); + if (!n) + /* Don't create an alias to an unreferenced function. */ + return; + } + + bool existed; + tree *slot = &mangled_decls->get_or_insert (id2, &existed); + /* 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. */ + if (existed) return; tree alias = make_alias_for (decl, id2); - SET_IDENTIFIER_GLOBAL_VALUE (id2, alias); + *slot = 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) + + if (n) n->create_same_body_alias (alias, decl); else varpool_node::create_extra_name_alias (alias, decl); @@ -4347,6 +4360,50 @@ generate_mangling_aliases () defer_mangling_aliases = false; } +/* Record a mangling of DECL, whose DECL_ASSEMBLER_NAME has just been + set. NEED_WARNING is true if we must warn about collisions. We do + this to spot changes in mangling that may require compatibility + aliases. */ + +void +record_mangling (tree decl, bool need_warning) +{ + if (!mangled_decls) + mangled_decls = hash_map::create_ggc (499); + + gcc_checking_assert (DECL_ASSEMBLER_NAME_SET_P (decl)); + tree id = DECL_ASSEMBLER_NAME (decl); + bool existed; + tree *slot = &mangled_decls->get_or_insert (id, &existed); + + /* If this is already an alias, remove the alias, because the real + decl takes presidence. */ + if (!existed) + ; + else if (DECL_ARTIFICIAL (*slot) && DECL_IGNORED_P (*slot)) + if (symtab_node *n = symtab_node::get (*slot)) + if (n->cpp_implicit_alias) + { + n->remove (); + existed = false; + } + + if (!existed) + *slot = decl; + else if (need_warning) + { + error_at (DECL_SOURCE_LOCATION (decl), + "mangling of %q#D as %qE conflicts with a previous mangle", + decl, id); + inform (DECL_SOURCE_LOCATION (*slot), + "previous mangling %q#D", *slot); + inform (DECL_SOURCE_LOCATION (decl), + "a later -fabi-version= (or =0)" + " avoids this error with a change in mangling"); + *slot = decl; + } +} + /* The entire file is now complete. If requested, dump everything to a file. */ diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 33cd00e3314..6046906e77d 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -3783,38 +3783,6 @@ get_mangled_id (tree decl) return targetm.mangle_decl_assembler_name (decl, id); } -/* If DECL is an implicit mangling alias, return its symtab node; otherwise - return NULL. */ - -static symtab_node * -decl_implicit_alias_p (tree decl) -{ - if (DECL_P (decl) && DECL_ARTIFICIAL (decl) - && DECL_IGNORED_P (decl) - && (TREE_CODE (decl) == FUNCTION_DECL - || (VAR_P (decl) && TREE_STATIC (decl)))) - { - symtab_node *n = symtab_node::get (decl); - if (n && n->cpp_implicit_alias) - return n; - } - return NULL; -} - -/* If DECL is a mangling alias, remove it from the symbol table and return - true; otherwise return false. */ - -bool -maybe_remove_implicit_alias (tree decl) -{ - if (symtab_node *n = decl_implicit_alias_p (decl)) - { - n->remove(); - return true; - } - return false; -} - /* Create an identifier for the external mangled name of DECL. */ void @@ -3871,29 +3839,11 @@ mangle_decl (const tree decl) if (!DECL_REALLY_EXTERN (decl)) { - bool set = false; - - /* Check IDENTIFIER_GLOBAL_VALUE before setting to avoid redundant - errors from multiple definitions. */ - tree d = IDENTIFIER_GLOBAL_VALUE (id); - if (!d || decl_implicit_alias_p (d)) - { - set = true; - SET_IDENTIFIER_GLOBAL_VALUE (id, decl); - } + record_mangling (decl, G.need_abi_warning); if (!G.need_abi_warning) return; - /* If the mangling will change in the future, emit an alias with the - future mangled name for forward-compatibility. */ - if (!set) - { - SET_IDENTIFIER_GLOBAL_VALUE (id, decl); - inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or " - "=0) avoids this error with a change in mangling"); - } - flag_abi_version = flag_abi_compat_version; id2 = mangle_decl_string (decl); id2 = targetm.mangle_decl_assembler_name (decl, id2); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 6763a5b9c68..0111d8de899 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2255,12 +2255,6 @@ supplement_binding_1 (cxx_binding *binding, tree decl) region to refer only to the namespace to which it already refers. */ ok = false; - else if (maybe_remove_implicit_alias (bval)) - { - /* There was a mangling compatibility alias using this mangled name, - but now we have a real decl that wants to use it instead. */ - binding->value = decl; - } else { if (!error_operand_p (bval)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0153b3d0458..26ca5563af4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-10-04 Nathan Sidwell + + * g++.dg/abi/mangle41.C: Adjust diagnostics. + 2017-10-04 Jakub Jelinek PR c++/82373 diff --git a/gcc/testsuite/g++.dg/abi/mangle41.C b/gcc/testsuite/g++.dg/abi/mangle41.C index 5fa47f16526..9da72f11feb 100644 --- a/gcc/testsuite/g++.dg/abi/mangle41.C +++ b/gcc/testsuite/g++.dg/abi/mangle41.C @@ -3,6 +3,6 @@ // { dg-options "-mavx -fabi-version=2" } #include -void f(__m128) { } // { dg-message "previous declaration" } -void f(__m256) { } // { dg-error "conflicts" } +void f(__m128) { } // { dg-message "previous mangling" } +void f(__m256) { } // { dg-error "conflicts with a previous mangle" } // { dg-message "mangling" "" { target *-*-* } .-1 } diff --git a/libcc1/ChangeLog b/libcc1/ChangeLog index 4d8f40c8312..ea7a1aeb25b 100644 --- a/libcc1/ChangeLog +++ b/libcc1/ChangeLog @@ -1,3 +1,8 @@ +2017-10-04 Nathan Sidwell + + * libcp1plugin.cc (supplement_binding): Don't use + maybe_remove_implicit_alias. + 2017-07-20 Nathan Sidwell Remove TYPE_METHODS. diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc index d7bf5a29d6d..12ea4ed84e0 100644 --- a/libcc1/libcp1plugin.cc +++ b/libcc1/libcp1plugin.cc @@ -422,12 +422,6 @@ supplement_binding (cxx_binding *binding, tree decl) region to refer only to the namespace to which it already refers. */ ok = false; - else if (maybe_remove_implicit_alias (bval)) - { - /* There was a mangling compatibility alias using this mangled name, - but now we have a real decl that wants to use it instead. */ - binding->value = decl; - } else { // _1: diagnose_name_conflict (decl, bval); -- 2.30.2