[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
This commit is contained in:
Nathan Sidwell 2017-10-04 16:55:54 +00:00 committed by Nathan Sidwell
parent baf20d8df2
commit b419102c12
9 changed files with 93 additions and 75 deletions

View File

@ -1,3 +1,17 @@
2017-10-04 Nathan Sidwell <nathan@acm.org>
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 <jakub@redhat.com>
PR c++/82373

View File

@ -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);

View File

@ -102,6 +102,10 @@ static GTY(()) vec<tree, va_gc> *no_linkage_decls;
is to be an alias for the former if the former is defined. */
static GTY(()) vec<tree, va_gc> *mangling_aliases;
/* A hash table of mangled names to decls. Used to figure out if we
need compatibility aliases. */
static GTY(()) hash_map<lang_identifier *, tree> *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<lang_identifier *, tree>::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. */

View File

@ -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);

View File

@ -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))

View File

@ -1,3 +1,7 @@
2017-10-04 Nathan Sidwell <nathan@acm.org>
* g++.dg/abi/mangle41.C: Adjust diagnostics.
2017-10-04 Jakub Jelinek <jakub@redhat.com>
PR c++/82373

View File

@ -3,6 +3,6 @@
// { dg-options "-mavx -fabi-version=2" }
#include <x86intrin.h>
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 }

View File

@ -1,3 +1,8 @@
2017-10-04 Nathan Sidwell <nathan@acm.org>
* libcp1plugin.cc (supplement_binding): Don't use
maybe_remove_implicit_alias.
2017-07-20 Nathan Sidwell <nathan@acm.org>
Remove TYPE_METHODS.

View File

@ -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);