re PR c++/44282 (fastcall is not mangled at all)
authorJason Merrill <jason@redhat.com>
Wed, 3 Jun 2015 21:09:25 +0000 (17:09 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 3 Jun 2015 21:09:25 +0000 (17:09 -0400)
PR c++/44282
* mangle.c (mangle_decl): Always SET_IDENTIFIER_GLOBAL_VALUE.
(write_CV_qualifiers_for_type): Set G.need_abi_warning.
(decl_implicit_alias_p): Split out from maybe_remove_implicit_alias.
* cp-tree.h (DECL_REALLY_EXTERN): Handle null DECL_LANG_SPECIFIC.

From-SVN: r224101

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/mangle.c
gcc/testsuite/g++.dg/abi/mangle-regparm.C
gcc/testsuite/g++.dg/abi/mangle58.C

index 39888b970b0ee1f6c884c8f78a225dc101562286..a9be43a8ffc13894c2c7acc91a315ca38c0e7a45 100644 (file)
@@ -1,3 +1,11 @@
+2015-06-03  Jason Merrill  <jason@redhat.com>
+
+       PR c++/44282
+       * mangle.c (mangle_decl): Always SET_IDENTIFIER_GLOBAL_VALUE.
+       (write_CV_qualifiers_for_type): Set G.need_abi_warning.
+       (decl_implicit_alias_p): Split out from maybe_remove_implicit_alias.
+       * cp-tree.h (DECL_REALLY_EXTERN): Handle null DECL_LANG_SPECIFIC.
+
 2015-06-03  Manuel López-Ibáñez  <manu@gcc.gnu.org>
            Paolo Carlini  <paolo.carlini@oracle.com>
 
index 76be7cca6f12656b3d3b72436006c7839f32729f..7690af77d8d0393a42c72748501d6ff3839a6532 100644 (file)
@@ -4101,7 +4101,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
   (DECL_LANG_SPECIFIC (NODE)->u.base.not_really_extern)
 
 #define DECL_REALLY_EXTERN(NODE) \
-  (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE))
+  (DECL_EXTERNAL (NODE)                                \
+   && (!DECL_LANG_SPECIFIC (NODE) || !DECL_NOT_REALLY_EXTERN (NODE)))
 
 /* A thunk is a stub function.
 
index 8fd06e3c2cd481d22b67374c743bd0652c1506d2..cc5faf7755ed49105e9d973bc92a8970b58e7729 100644 (file)
@@ -2205,10 +2205,6 @@ write_CV_qualifiers_for_type (const tree type)
 
   /* Mangle attributes that affect type identity as extended qualifiers.
 
-     We mangle them onto the obstack, then copy the result into a string
-     vector and back up the obstack.  Once we've handled all of them we
-     sort them and write them out in order.
-
      We don't do this with classes and enums because their attributes
      are part of their definitions, not something added on.  */
 
@@ -2246,6 +2242,8 @@ write_CV_qualifiers_for_type (const tree type)
            }
 
          ++num_qualifiers;
+         if (abi_version_crosses (9))
+           G.need_abi_warning = true;
        }
     }
 
@@ -3535,11 +3533,11 @@ get_mangled_id (tree decl)
   return targetm.mangle_decl_assembler_name (decl, id);
 }
 
-/* If DECL is a mangling alias, remove it from the symbol table and return
-   true; otherwise return false.  */
+/* If DECL is an implicit mangling alias, return its symtab node; otherwise
+   return NULL.  */
 
-bool
-maybe_remove_implicit_alias (tree decl)
+static symtab_node *
+decl_implicit_alias_p (tree decl)
 {
   if (DECL_P (decl) && DECL_ARTIFICIAL (decl)
       && DECL_IGNORED_P (decl)
@@ -3549,10 +3547,21 @@ maybe_remove_implicit_alias (tree decl)
     {
       symtab_node *n = symtab_node::get (decl);
       if (n && n->cpp_implicit_alias)
-       {
-         n->remove();
-         return true;
-       }
+       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;
 }
@@ -3592,21 +3601,38 @@ mangle_decl (const tree decl)
     }
   SET_DECL_ASSEMBLER_NAME (decl, id);
 
-  if (G.need_abi_warning
+  if (id != DECL_NAME (decl)
+      && !DECL_REALLY_EXTERN (decl)
       /* Don't do this for a fake symbol we aren't going to emit anyway.  */
       && TREE_CODE (decl) != TYPE_DECL
       && !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
       && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (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);
+       }
+
+      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.  */
       int save_ver;
       tree id2;
 
-      SET_IDENTIFIER_GLOBAL_VALUE (id, decl);
-      if (IDENTIFIER_GLOBAL_VALUE (id) != decl)
-       inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or =0) "
-               "avoids this error with a change in mangling");
+      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");
+       }
 
       save_ver = flag_abi_version;
       flag_abi_version = flag_abi_compat_version;
index e5d6f37e639510b82c00e955634fc4675d0828f0..122d37390db7f50f0a0b9d651d93467df5030f0c 100644 (file)
@@ -1,10 +1,11 @@
 // { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } }
+// { dg-options "-Wabi=8" }
 // { dg-final { scan-assembler "_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_" } }
 
 typedef __SIZE_TYPE__ size_t;
 
 template <typename F, typename T>
-void IndirectExternCall(F f, T t1, T t2) {
+void IndirectExternCall(F f, T t1, T t2) { // { dg-warning "mangled name" }
   typedef F (*WrapF)(F);
   f (t1, t2);
 }
index f9aadc2a9008702446c984ff26466da0563cd8c3..d2c90b43a2d415870caaef007439d77d7fa31c06 100644 (file)
@@ -6,13 +6,13 @@ struct B {
   template<typename T> static int cmp1(T a, T b);
   static int cmp2(char a, char b);
   // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_X4cmp1EE" } }
-  template <typename T> static void f (A<T,cmp1> &);
+  template <typename T> static void f (A<T,cmp1> &) {}
   // { dg-final { scan-assembler "_ZN1B1gIcEEvR1AIT_XsrS_4cmp1EE" } }
-  template <typename T> static void g (A<T,B::cmp1> &);
+  template <typename T> static void g (A<T,B::cmp1> &) {}
   // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_L_ZNS_4cmp2EccEE" } }
-  template <typename T> static void f (A<T,cmp2> &); // { dg-warning "mangle" }
+  template <typename T> static void f (A<T,cmp2> &) {} // { dg-warning "mangle" }
   // { dg-final { scan-assembler "_ZN1B1gIcEEvR1AIT_L_ZNS_4cmp2EccEE" } }
-  template <typename T> static void g (A<T,B::cmp2> &); // { dg-warning "mangle" }
+  template <typename T> static void g (A<T,B::cmp2> &) {} // { dg-warning "mangle" }
 };
 
 void g()