pt.c (lookup_template_class_1): Splice out abi_tag attribute if necessary.
authorJason Merrill <jason@redhat.com>
Tue, 16 Sep 2014 02:36:12 +0000 (22:36 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 16 Sep 2014 02:36:12 +0000 (22:36 -0400)
* pt.c (lookup_template_class_1): Splice out abi_tag attribute if
necessary.  Call inherit_targ_abi_tags here.
* class.c (check_bases_and_members): Not here.
(inherit_targ_abi_tags): Check CLASS_TYPE_P.
* cp-tree.h: Declare inherit_targ_abi_tags.

From-SVN: r215283

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/testsuite/g++.dg/abi/abi-tag10.C [new file with mode: 0644]

index 7e1b0f9f78dca15a8a23151fe5a15aac70ca7940..1e79182e86e70fd33030360470f775d62add41bd 100644 (file)
@@ -1,3 +1,11 @@
+2014-09-15  Jason Merrill  <jason@redhat.com>
+
+       * pt.c (lookup_template_class_1): Splice out abi_tag attribute if
+       necessary.  Call inherit_targ_abi_tags here.
+       * class.c (check_bases_and_members): Not here.
+       (inherit_targ_abi_tags): Check CLASS_TYPE_P.
+       * cp-tree.h: Declare inherit_targ_abi_tags.
+
 2014-09-15  Ville Voutilainen  <ville.voutilainen@gmail.com>
 
        Do not diagnose lambda default arguments in c++14 modes.
index 09f946fcdf7c45eef7c09dffe99ee71ed49c18a3..6b86ef4d9235a0de5859579d9cbd6565f427b177 100644 (file)
@@ -1441,7 +1441,8 @@ check_abi_tags (tree t, tree subob)
 void
 inherit_targ_abi_tags (tree t)
 {
-  if (CLASSTYPE_TEMPLATE_INFO (t) == NULL_TREE)
+  if (!CLASS_TYPE_P (t)
+      || CLASSTYPE_TEMPLATE_INFO (t) == NULL_TREE)
     return;
 
   mark_type_abi_tags (t, true);
@@ -5460,9 +5461,6 @@ check_bases_and_members (tree t)
   bool saved_nontrivial_dtor;
   tree fn;
 
-  /* Pick up any abi_tags from our template arguments before checking.  */
-  inherit_targ_abi_tags (t);
-
   /* By default, we use const reference arguments and generate default
      constructors.  */
   cant_have_const_ctor = 0;
index 19f52329f25fd5d79ee9bb9af6c3cac0418e6993..5d8badcfe7556083ffc89e6e57a706383d64ea95 100644 (file)
@@ -5206,6 +5206,7 @@ extern bool type_has_user_declared_move_assign(tree);
 extern bool type_build_ctor_call               (tree);
 extern bool type_build_dtor_call               (tree);
 extern void explain_non_literal_class          (tree);
+extern void inherit_targ_abi_tags              (tree);
 extern void defaulted_late_check               (tree);
 extern bool defaultable_fn_check               (tree);
 extern void fixup_type_variants                        (tree);
index 008879b28d5da49fcf6dfcdc6ca25c9a6feb12e2..b3a9c95ac609d4508a95a295353e5529e8252834 100644 (file)
@@ -7823,9 +7823,18 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
 
       if (OVERLOAD_TYPE_P (t)
          && !DECL_ALIAS_TEMPLATE_P (gen_tmpl))
-       if (tree attributes
-           = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (template_type)))
-         TYPE_ATTRIBUTES (t) = attributes;
+       {
+         if (tree attributes
+             = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (template_type)))
+           {
+             if (!TREE_CHAIN (attributes))
+               TYPE_ATTRIBUTES (t) = attributes;
+             else
+               TYPE_ATTRIBUTES (t)
+                 = build_tree_list (TREE_PURPOSE (attributes),
+                                    TREE_VALUE (attributes));
+           }
+       }
 
       /* Let's consider the explicit specialization of a member
          of a class template specialization that is implicitly instantiated,
@@ -7950,6 +7959,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
       TREE_PUBLIC (type_decl) = 1;
       determine_visibility (type_decl);
 
+      inherit_targ_abi_tags (t);
+
       return t;
     }
 }
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag10.C b/gcc/testsuite/g++.dg/abi/abi-tag10.C
new file mode 100644 (file)
index 0000000..f320828
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef ABI_TAG
+#define ABI_TAG __attribute__((__abi_tag__("cxx11")))
+#endif
+
+typedef unsigned long size_t;
+
+template<typename C>
+struct char_traits { };
+template<typename C>
+struct allocator { };
+
+template<typename C, typename T = char_traits<C>, typename A = allocator<C> >
+struct ABI_TAG basic_string { };
+
+typedef basic_string<char> string;
+
+template<typename T>
+struct hash
+{
+  size_t
+  operator()(T val) const;
+};
+
+template<>
+size_t
+hash<string>::operator()(string) const { return 0; }
+
+// { dg-final { scan-assembler "_ZNK4hashI12basic_stringB5cxx11Ic11char_traitsIcE9allocatorIcEEEclES5_" } }