PR c++/71712 - ABI tags on conversion ops.
authorJason Merrill <jason@redhat.com>
Tue, 9 Aug 2016 16:55:08 +0000 (12:55 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 9 Aug 2016 16:55:08 +0000 (12:55 -0400)
* class.c (check_abi_tags): Don't duplicate tags for conversion ops.

From-SVN: r239299

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/mangle.c
gcc/testsuite/g++.dg/abi/abi-tag22.C [new file with mode: 0644]
gcc/testsuite/g++.dg/abi/abi-tag22a.C [new file with mode: 0644]

index 81ca1a1b04f473c5721d9b2a44b02a9471e8a1ee..c71ea1703c87eae2309b7e8fc3313f3ba0916bcc 100644 (file)
@@ -1,5 +1,8 @@
 2016-08-09  Jason Merrill  <jason@redhat.com>
 
+       PR c++/71712
+       * class.c (check_abi_tags): Don't duplicate tags for conversion ops.
+
        Adjust mangling of ABI tags on class template member functions.
        * class.c (missing_abi_tags): New.
        (check_abi_tags): Don't check template. Add just_checking mode.
index e21647a642eff4b23c4208fc4560553274eaab17..10286a7404e15e99c93fb9eaa12ca52b1c39e329 100644 (file)
@@ -1618,6 +1618,7 @@ check_abi_tags (tree decl)
   if (VAR_P (decl))
     check_abi_tags (decl, TREE_TYPE (decl));
   else if (TREE_CODE (decl) == FUNCTION_DECL
+          && !DECL_CONV_FN_P (decl)
           && !mangle_return_type_p (decl))
     check_abi_tags (decl, TREE_TYPE (TREE_TYPE (decl)));
 }
@@ -1632,6 +1633,9 @@ missing_abi_tags (tree decl)
   if (VAR_P (decl))
     return check_abi_tags (decl, TREE_TYPE (decl), true);
   else if (TREE_CODE (decl) == FUNCTION_DECL
+          /* Don't check DECL_CONV_FN_P here like we do in check_abi_tags, so
+             that we can use this function for setting need_abi_warning
+             regardless of the current flag_abi_version.  */
           && !mangle_return_type_p (decl))
     return check_abi_tags (decl, TREE_TYPE (TREE_TYPE (decl)), true);
   else
index f7ff221d9416d3faf0369e5fded1d6bf4c3f1bf5..b42c6f9214929489645156cc3ddab33d20e83bd6 100644 (file)
@@ -1383,6 +1383,15 @@ write_unqualified_name (tree decl)
     }
 
   tree tags = get_abi_tags (decl);
+  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CONV_FN_P (decl)
+      && any_abi_below (11))
+    if (tree mtags = missing_abi_tags (decl))
+      {
+       if (abi_warn_or_compat_version_crosses (11))
+         G.need_abi_warning = true;
+       if (!abi_version_at_least (11))
+         tags = chainon (mtags, tags);
+      }
   write_abi_tags (tags);
 }
 
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag22.C b/gcc/testsuite/g++.dg/abi/abi-tag22.C
new file mode 100644 (file)
index 0000000..e649233
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/71712
+// { dg-options -Wabi=10 }
+
+struct __attribute__((abi_tag("A", "B"))) A { };
+struct A18 {
+  operator A();                        // { dg-warning "mangled name" }
+};
+void f18_test() {
+  // { dg-final { scan-assembler "_ZN3A18cv1AB1AB1BEv" } }
+  A a = A18();
+}
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag22a.C b/gcc/testsuite/g++.dg/abi/abi-tag22a.C
new file mode 100644 (file)
index 0000000..c27fac6
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/71712
+// { dg-options "-fabi-version=10 -Wabi" }
+
+struct __attribute__((abi_tag("A", "B"))) A { };
+struct A18 {
+  operator A();                        // { dg-warning "mangled name" }
+};
+void f18_test() {
+  // { dg-final { scan-assembler "_ZN3A18cv1AB1AB1BB1AB1BEv" } }
+  A a = A18();
+}