This bug report pointed out that we weren't properly decorating template
mangled names with the appropriate abi_tags. This patch fixes this by
making sure that the mangler only looks at the abi_tag from the
template, and the parser warns that we'll ignore tags on specializations
and instantiations. This means a change of mangling in abi-tag3.C, but
this is necessary to handle incomplete types properly; we need to be
able to name the type without requiring it to be defined.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 661d8194dd1ffd442f658934608a30c9cd8f78a4
Author: Jason Merrill <ja...@redhat.com>
Date: Wed Mar 26 16:19:32 2014 -0400
PR c++/60642
* mangle.c (write_unqualified_name): Handle abi tag on class
template properly.
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 251edb1..7fee6fa 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1280,7 +1280,8 @@ write_unqualified_name (const tree decl)
write_source_name (DECL_NAME (decl));
}
- tree attrs = (TREE_CODE (decl) == TYPE_DECL
+ tree attrs = ((TREE_CODE (decl) == TYPE_DECL
+ || DECL_CLASS_TEMPLATE_P (decl))
? TYPE_ATTRIBUTES (TREE_TYPE (decl))
: DECL_ATTRIBUTES (decl));
write_abi_tags (lookup_attribute ("abi_tag", attrs));
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c791d03..8ca8640 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7834,6 +7834,15 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
code that generates debugging information will crash. */
DECL_IGNORED_P (TYPE_MAIN_DECL (t)) = 1;
+ /* ABI tags apply to the template name, not an instantiation. */
+ if (tree attr
+ = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (template_type)))
+ {
+ attr = copy_node (attr);
+ TREE_CHAIN (attr) = NULL_TREE;
+ TYPE_ATTRIBUTES (t) = attr;
+ }
+
/* Possibly limit visibility based on template args. */
TREE_PUBLIC (type_decl) = 1;
determine_visibility (type_decl);
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index f9114ab..819e640 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -17542,6 +17542,9 @@ unimportant.
A redeclaration of a function or class must not add new ABI tags,
since doing so would change the mangled name.
+The ABI tags apply to a name, so all instantiations and
+specializations of a template have the same tags.
+
The @option{-Wabi-tag} flag enables a warning about a class which does
not have all the ABI tags used by its subobjects and virtual functions; for users with code
that needs to coexist with an earlier ABI, using this option can help
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag3.C b/gcc/testsuite/g++.dg/abi/abi-tag3.C
index 05fd58e..73ec13e 100644
--- a/gcc/testsuite/g++.dg/abi/abi-tag3.C
+++ b/gcc/testsuite/g++.dg/abi/abi-tag3.C
@@ -1,5 +1,4 @@
-// An explicit specialization doesn't get the tag from its template unless
-// it is specified there, too.
+// An explicit specialization gets the tag from its template.
// { dg-final { scan-assembler "_ZN3FooB5cxx11IcE1fEv" } }
template<typename T>
@@ -17,7 +16,7 @@ Foo<int>
int f();
};
-// { dg-final { scan-assembler "_ZN3FooIdE1fEv" } }
+// { dg-final { scan-assembler "_ZN3FooB5cxx11IdE1fEv" } }
template<>
struct
Foo<double>
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag6.C b/gcc/testsuite/g++.dg/abi/abi-tag6.C
new file mode 100644
index 0000000..94ea2f3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/abi-tag6.C
@@ -0,0 +1,25 @@
+// PR c++/60642
+
+struct __attribute((abi_tag("test"))) foo
+{
+ void f();
+ virtual ~foo();
+};
+
+template<typename>
+struct __attribute((abi_tag("test"))) bar
+{
+ void f();
+ virtual ~bar();
+};
+
+int main()
+{
+ foo f;
+ f.f();
+
+ bar<int> b;
+ b.f();
+}
+
+// { dg-final { scan-assembler "_ZTV3barB4testIiE" } }
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag7.C b/gcc/testsuite/g++.dg/abi/abi-tag7.C
new file mode 100644
index 0000000..1df20a4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/abi-tag7.C
@@ -0,0 +1,9 @@
+// PR c++/60642
+
+template<typename T>
+class __attribute((abi_tag("foo"))) test{ };
+
+template class __attribute((abi_tag("foo"))) test<int>;
+
+void f(test<char>*) {}
+// { dg-final { scan-assembler "_Z1fP4testB3fooIcE" } }