commit 661d8194dd1ffd442f658934608a30c9cd8f78a4
Author: Jason Merrill <jason@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.
@@ -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));
@@ -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);
@@ -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
@@ -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>
new file mode 100644
@@ -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" } }
new file mode 100644
@@ -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" } }