This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/60642 (abi_tag and templates)


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 <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.

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" } }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]