[C++ PATCH] Move mangling alias out of ::
authorNathan Sidwell <nathan@acm.org>
Wed, 4 Oct 2017 16:55:54 +0000 (16:55 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 4 Oct 2017 16:55:54 +0000 (16:55 +0000)
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
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/mangle.c
gcc/cp/name-lookup.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/mangle41.C
libcc1/ChangeLog
libcc1/libcp1plugin.cc

index 18e4b9997b6bdeeccd6bb62e88dc0b8c1b61f39c..01b8c4d6da60a4a1c84d6d01be2aacc6903a770b 100644 (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
index a21c948539342a784075b94e6a1d66da2b691cf9..82ebc2831c586e3952b0c03f7132066bf34bc32e 100644 (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);
index eb9c6a59e047a1a2281e93203b7b9089b6fbe39b..354d503da6d5dc1b14beab0aab04b7381bc5ff60 100644 (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.  */
 
index 33cd00e33147ee00a222854773d370bf18c2423e..6046906e77d76b56246144b48dbccc8120423557 100644 (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);
index 6763a5b9c68254f978f32d151ff9a6e0e01307b7..0111d8de899c646a922dee0e8c247c4259af094e 100644 (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))
index 0153b3d0458c32c29041276736dcc56430ec32ed..26ca5563af4278b07916d0a7805820faae5a5292 100644 (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
index 5fa47f1652661a6f3f08a65734e6e9f27294955d..9da72f11feb69ad8d613ce20b6f0bbe06aa8eb66 100644 (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 }
index 4d8f40c83123522fa8f6f54566438e19241a5ae9..ea7a1aeb25b3995ae82734e9a25136a22ca42b8c 100644 (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.
index d7bf5a29d6d0019a3a87aeb6979814aebf6721d3..12ea4ed84e0d329fa035ca317fb1ea5bef3dc300 100644 (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);