+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
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);
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);
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;
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);
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. */
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
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);
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))
+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
// { 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 }
+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.
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);