re PR c++/44282 (fastcall is not mangled at all)
authorJason Merrill <jason@redhat.com>
Tue, 2 Jun 2015 02:28:19 +0000 (22:28 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 2 Jun 2015 02:28:19 +0000 (22:28 -0400)
PR c++/44282
gcc/cp/
* mangle.c (attr_strcmp): New.
(write_CV_qualifiers_for_type): Also write out attributes that
affect type identity.
(write_type): Strip all attributes after writing qualifiers.
libiberty/
* cp-demangle.c (cplus_demangle_type): Handle arguments to vendor
extended qualifier.

From-SVN: r224007

gcc/c-family/c-opts.c
gcc/common.opt
gcc/cp/ChangeLog
gcc/cp/mangle.c
gcc/testsuite/g++.dg/abi/macro0.C
gcc/testsuite/g++.dg/abi/mangle-regparm.C [new file with mode: 0644]
libiberty/ChangeLog
libiberty/cp-demangle.c
libiberty/testsuite/demangle-expected

index fe5fce78597f0600b6132797e1fdb04296206064..8996fe3a9e62ef3fabd5e8301d9d9e93a7dfaec4 100644 (file)
@@ -894,7 +894,7 @@ c_common_post_options (const char **pfilename)
   /* Change flag_abi_version to be the actual current ABI level for the
      benefit of c_cpp_builtins.  */
   if (flag_abi_version == 0)
-    flag_abi_version = 8;
+    flag_abi_version = 9;
 
   /* Set C++ standard to C++98 if not specified on the command line.  */
   if (c_dialect_cxx () && cxx_dialect == cxx_unset)
index 6e15af2e189a1f1503af79a2de8b8b94d1d9eb7d..32b416a324f8fe7c06b99a2926423b4d88b727f8 100644 (file)
@@ -836,8 +836,11 @@ Driver Undocumented
 ;
 ; 8: The version of the ABI that corrects the substitution behavior of
 ;    function types with function-cv-qualifiers.
-;    First selectable in G++ 4.9 and default in G++ 5
-;    (set in c_common_post_options).
+;    First selectable in G++ 4.9 and default in G++ 5.
+;
+; 9: The version of the ABI that mangles attributes that affect type
+;    identity, such as ia32 calling convention attributes (stdcall, etc.)
+;    Default in G++ 6 (set in c_common_post_options).
 ;
 ; Additional positive integers will be assigned as new versions of
 ; the ABI become the default version of the ABI.
index 467449c5fbd314562c7a3f5fc2ae03c767742210..78d779133a6ebe8cea6f114b214c2ae5aef035e2 100644 (file)
@@ -1,3 +1,11 @@
+2015-06-01  Jason Merrill  <jason@redhat.com>
+
+       PR c++/44282
+       * mangle.c (attr_strcmp): New.
+       (write_CV_qualifiers_for_type): Also write out attributes that
+       affect type identity.
+       (write_type): Strip all attributes after writing qualifiers.
+
 2015-05-31  Jason Merrill  <jason@redhat.com>
 
        * constexpr.c (cxx_eval_indirect_ref): Try folding first.
index aa466cdd0fee34c0d3ccde246f64c002940db7b7..8fd06e3c2cd481d22b67374c743bd0652c1506d2 100644 (file)
@@ -75,6 +75,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "wide-int.h"
+#include "attribs.h"
 
 /* Debugging support.  */
 
@@ -1916,11 +1917,15 @@ write_type (tree type)
        candidates.  */
     {
       tree t = TYPE_MAIN_VARIANT (type);
+      if (TYPE_ATTRIBUTES (t) && !OVERLOAD_TYPE_P (t))
+       t = cp_build_type_attribute_variant (t, NULL_TREE);
+      gcc_assert (t != type);
       if (TREE_CODE (t) == FUNCTION_TYPE
          || TREE_CODE (t) == METHOD_TYPE)
        {
          t = build_ref_qualified_type (t, type_memfn_rqual (type));
-         if (abi_version_at_least (8))
+         if (abi_version_at_least (8)
+             || type == TYPE_MAIN_VARIANT (type))
            /* Avoid adding the unqualified function type as a substitution.  */
            write_function_type (t);
          else
@@ -2168,6 +2173,20 @@ write_type (tree type)
     add_substitution (type);
 }
 
+/* qsort callback for sorting a vector of attribute entries.  */
+
+static int
+attr_strcmp (const void *p1, const void *p2)
+{
+  tree a1 = *(const tree*)p1;
+  tree a2 = *(const tree*)p2;
+
+  const attribute_spec *as1 = lookup_attribute_spec (get_attribute_name (a1));
+  const attribute_spec *as2 = lookup_attribute_spec (get_attribute_name (a2));
+
+  return strcmp (as1->name, as2->name);
+}
+
 /* Non-terminal <CV-qualifiers> for type nodes.  Returns the number of
    CV-qualifiers written for TYPE.
 
@@ -2182,9 +2201,55 @@ write_CV_qualifiers_for_type (const tree type)
 
        "In cases where multiple order-insensitive qualifiers are
        present, they should be ordered 'K' (closest to the base type),
-       'V', 'r', and 'U' (farthest from the base type) ..."
+       'V', 'r', and 'U' (farthest from the base 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.  */
+
+  if (abi_version_at_least (9) && !OVERLOAD_TYPE_P (type))
+    {
+      auto_vec<tree> vec;
+      for (tree a = TYPE_ATTRIBUTES (type); a; a = TREE_CHAIN (a))
+       {
+         tree name = get_attribute_name (a);
+         const attribute_spec *as = lookup_attribute_spec (name);
+         if (as && as->affects_type_identity
+             && !is_attribute_p ("abi_tag", name))
+           vec.safe_push (a);
+       }
+      vec.qsort (attr_strcmp);
+      while (!vec.is_empty())
+       {
+         tree a = vec.pop();
+         const attribute_spec *as
+           = lookup_attribute_spec (get_attribute_name (a));
+
+         write_char ('U');
+         write_unsigned_number (strlen (as->name));
+         write_string (as->name);
+         if (TREE_VALUE (a))
+           {
+             write_char ('I');
+             for (tree args = TREE_VALUE (a); args;
+                  args = TREE_CHAIN (args))
+               {
+                 tree arg = TREE_VALUE (args);
+                 write_template_arg (arg);
+               }
+             write_char ('E');
+           }
+
+         ++num_qualifiers;
+       }
+    }
 
-     Note that we do not use cp_type_quals below; given "const
+  /* Note that we do not use cp_type_quals below; given "const
      int[3]", the "const" is emitted with the "int", not with the
      array.  */
   cp_cv_quals quals = TYPE_QUALS (type);
index fbcbb2cdc9648a8940c16d99692707bffa8da2bd..35b8769c3d3e771acc4ac028535580f088688bfe 100644 (file)
@@ -1,6 +1,6 @@
 // This testcase will need to be kept in sync with c_common_post_options.
 // { dg-options "-fabi-version=0" }
 
-#if __GXX_ABI_VERSION != 1008
+#if __GXX_ABI_VERSION != 1009
 #error "Incorrect value of __GXX_ABI_VERSION"
 #endif
diff --git a/gcc/testsuite/g++.dg/abi/mangle-regparm.C b/gcc/testsuite/g++.dg/abi/mangle-regparm.C
new file mode 100644 (file)
index 0000000..7d4121b
--- /dev/null
@@ -0,0 +1,29 @@
+// { dg-do run { target i?86-*-* } }
+// { 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) {
+  typedef F (*WrapF)(F);
+  f (t1, t2);
+}
+
+__attribute__((regparm(3), stdcall))
+void regparm_func (int i, int j)
+{
+  if (i != 24 || j != 42)
+    __builtin_abort();
+}
+
+void normal_func (int i, int j)
+{
+  if (i != 24 || j != 42)
+    __builtin_abort();
+}
+
+int main()
+{
+  IndirectExternCall (regparm_func, 24, 42);
+  IndirectExternCall (normal_func, 24, 42);
+}
index e9bc2c7df68447daf9af6e079d15e0ed7ae0e4de..f2b014841aae4b528b348af7c7e467d0f03fc6b8 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-01  Jason Merrill  <jason@redhat.com>
+
+       * cp-demangle.c (cplus_demangle_type): Handle arguments to vendor
+       extended qualifier.
+
 2015-05-22  Yunlian Jiang  <yunlian@google.com>
 
        * configure.ac: Add AC_GNU_SOURCE.
index 77c2cee9d176015ffd681b43e9f55db00b2801f4..2988b6bcb01a3be2108b87c10640c437daf4b068 100644 (file)
@@ -2470,6 +2470,9 @@ cplus_demangle_type (struct d_info *di)
     case 'U':
       d_advance (di, 1);
       ret = d_source_name (di);
+      if (d_peek_char (di) == 'I')
+       ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
+                          d_template_args (di));
       ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
                         cplus_demangle_type (di), ret);
       break;
index a030685de0894e130e784e609b8cb0e612d5857d..6ea64aef8591bb1a7104fa87ebd50b3740e1d3d3 100644 (file)
@@ -4356,3 +4356,6 @@ _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
 --format=gnu-v3
 _Z1fSsB3fooS_
 f(std::string[abi:foo], std::string[abi:foo])
+--format=gnu-v3
+_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_
+void IndirectExternCall<void ( regparm<3> stdcall*)(int, int), int>(void ( regparm<3> stdcall*)(int, int), int, void ( regparm<3> stdcall*)(int, int))