These patches fix a couple of abi_tag bugs that were reported to me
recently.
The first is an issue whereby all instantiations of a class template
were sharing tags, so instantiating a template with a tagged type
argument would apply the tag to another instantiation. Oops.
The second is an issue where the multiple-initialization guard for a
tagged variable was not itself tagged.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit ca11e70947cc2a94cc8ac2d07733f1f01904bba0
Author: Jason Merrill <ja...@redhat.com>
Date: Fri Jan 29 17:33:24 2016 +0100
* pt.c (lookup_template_class_1): Don't share TYPE_ATTRIBUTES
between template and instantiation.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 186a5d2..0d0e664 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8482,11 +8482,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
tree attributes
= lookup_attribute (tags[ix], TYPE_ATTRIBUTES (template_type));
- if (!attributes)
- ;
- else if (!TREE_CHAIN (attributes) && !TYPE_ATTRIBUTES (t))
- TYPE_ATTRIBUTES (t) = attributes;
- else
+ if (attributes)
TYPE_ATTRIBUTES (t)
= tree_cons (TREE_PURPOSE (attributes),
TREE_VALUE (attributes),
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag17.C b/gcc/testsuite/g++.dg/abi/abi-tag17.C
new file mode 100644
index 0000000..cb7dbab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/abi-tag17.C
@@ -0,0 +1,9 @@
+// { dg-final { scan-assembler "_Z3fi1B6_X_tagv" } }
+
+struct __attribute((abi_tag("_A1_tag"))) A1 {};
+template <class T> struct __attribute((abi_tag("_X_tag"))) X {};
+X<int> fi1();
+int main() {
+ X<A1> xa;
+ fi1();
+}
commit 615067ce890764a32a1fc6978ec17b6c1a2f4645
Author: Jason Merrill <ja...@redhat.com>
Date: Fri Jan 29 03:02:31 2016 -0500
* mangle.c (maybe_check_abi_tags): New.
(write_guarded_var_name): Call it.
(mangle_ref_init_variable): Call check_abi_tags.
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 4f1eea6..2bb7048 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -3931,6 +3931,30 @@ mangle_conv_op_name_for_type (const tree type)
return identifier;
}
+/* Handle ABI backwards compatibility for past bugs where we didn't call
+ check_abi_tags in places where it's needed: call check_abi_tags and warn if
+ it makes a difference. */
+
+static void
+maybe_check_abi_tags (tree t)
+{
+ tree attr = lookup_attribute ("abi_tag", DECL_ATTRIBUTES (t));
+ tree oldtags = NULL_TREE;
+ if (attr)
+ oldtags = TREE_VALUE (attr);
+
+ check_abi_tags (t);
+
+ if (!attr)
+ attr = lookup_attribute ("abi_tag", DECL_ATTRIBUTES (t));
+ if (attr && TREE_VALUE (attr) != oldtags
+ && abi_version_crosses (10))
+ warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi,
+ "the mangled name of the initialization guard variable for"
+ "%qD changes between -fabi-version=%d and -fabi-version=%d",
+ t, flag_abi_version, warn_abi_version);
+}
+
/* Write out the appropriate string for this variable when generating
another mangled name based on this one. */
@@ -3943,7 +3967,15 @@ write_guarded_var_name (const tree variable)
to the reference, not the temporary. */
write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
else
- write_name (variable, /*ignore_local_scope=*/0);
+ {
+ /* Before ABI v10 we were failing to call check_abi_tags here. So if
+ we're in pre-10 mode, wait until after write_name to call it. */
+ if (abi_version_at_least (10))
+ maybe_check_abi_tags (variable);
+ write_name (variable, /*ignore_local_scope=*/0);
+ if (!abi_version_at_least (10))
+ maybe_check_abi_tags (variable);
+ }
}
/* Return an identifier for the name of an initialization guard
@@ -4007,6 +4039,7 @@ mangle_ref_init_variable (const tree variable)
{
start_mangling (variable);
write_string ("_ZGR");
+ check_abi_tags (variable);
write_name (variable, /*ignore_local_scope=*/0);
/* Avoid name clashes with aggregate initialization of multiple
references at once. */
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag16.C b/gcc/testsuite/g++.dg/abi/abi-tag16.C
new file mode 100644
index 0000000..d4fa142
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/abi-tag16.C
@@ -0,0 +1,19 @@
+// { dg-options -Wabi=9 }
+// { dg-final { scan-assembler "_ZGVZN1N1FEvE4NameB5cxx11" } }
+namespace std {
+ __extension__ inline namespace __cxx11 __attribute__((abi_tag("cxx11"))) {
+ struct String {
+ String();
+ };
+ }
+}
+namespace N {
+ inline void F() {
+ {
+ static std::String Name; // { dg-warning "mangled name" }
+ }
+ }
+ void F2() {
+ F();
+ }
+}
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag16a.C b/gcc/testsuite/g++.dg/abi/abi-tag16a.C
new file mode 100644
index 0000000..b02e856
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/abi-tag16a.C
@@ -0,0 +1,19 @@
+// { dg-options "-fabi-version=9 -Wabi" }
+// { dg-final { scan-assembler "_ZGVZN1N1FEvE4Name" } }
+namespace std {
+ __extension__ inline namespace __cxx11 __attribute__((abi_tag("cxx11"))) {
+ struct String {
+ String();
+ };
+ }
+}
+namespace N {
+ inline void F() {
+ {
+ static std::String Name; // { dg-warning "mangled name" }
+ }
+ }
+ void F2() {
+ F();
+ }
+}