From: Jason Merrill Date: Tue, 16 Sep 2014 02:36:12 +0000 (-0400) Subject: pt.c (lookup_template_class_1): Splice out abi_tag attribute if necessary. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e93050426d180c5d22653e349e066331785521f0;p=gcc.git pt.c (lookup_template_class_1): Splice out abi_tag attribute if necessary. * 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7e1b0f9f78d..1e79182e86e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2014-09-15 Jason Merrill + + * 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 Do not diagnose lambda default arguments in c++14 modes. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 09f946fcdf7..6b86ef4d923 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 19f52329f25..5d8badcfe75 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 008879b28d5..b3a9c95ac60 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 index 00000000000..f3208285161 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/abi-tag10.C @@ -0,0 +1,28 @@ +#ifndef ABI_TAG +#define ABI_TAG __attribute__((__abi_tag__("cxx11"))) +#endif + +typedef unsigned long size_t; + +template +struct char_traits { }; +template +struct allocator { }; + +template, typename A = allocator > +struct ABI_TAG basic_string { }; + +typedef basic_string string; + +template +struct hash +{ + size_t + operator()(T val) const; +}; + +template<> +size_t +hash::operator()(string) const { return 0; } + +// { dg-final { scan-assembler "_ZNK4hashI12basic_stringB5cxx11Ic11char_traitsIcE9allocatorIcEEEclES5_" } }