On 01/31/2016 06:49 AM, Jason Merrill wrote:
These patches fix a couple of abi_tag bugs that were reported to me recently.
...
The second is an issue where the multiple-initialization guard for a tagged variable was not itself tagged.
That didn't completely fix the issue. Trying again:
commit 09ebcab51e037bc236bb804ca5cc5d27a2f1fb9b Author: Jason Merrill <ja...@redhat.com> Date: Fri Feb 19 00:51:35 2016 -0500 * mangle.c (maybe_check_abi_tags): Add for_decl parm. Call mangle_decl. (mangle_decl): Call maybe_check_abi_tags for function scope. (mangle_guard_variable): Call maybe_check_abi_tags here. (write_guarded_var_name): Not here. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 410c7f4..5d38373 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -223,6 +223,7 @@ static void write_local_name (tree, const tree, const tree); static void dump_substitution_candidates (void); static tree mangle_decl_string (const tree); static int local_class_index (tree); +static void maybe_check_abi_tags (tree, tree = NULL_TREE); /* Control functions. */ @@ -3599,6 +3600,9 @@ mangle_decl (const tree decl) { gcc_assert (TREE_CODE (decl) != TYPE_DECL || !no_linkage_check (TREE_TYPE (decl), true)); + if (abi_version_at_least (10)) + if (tree fn = decl_function_context (decl)) + maybe_check_abi_tags (fn, decl); id = get_mangled_id (decl); } SET_DECL_ASSEMBLER_NAME (decl, id); @@ -3937,26 +3941,39 @@ mangle_conv_op_name_for_type (const tree type) /* 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. */ + it makes a difference. If FOR_DECL is non-null, it's the declaration + that we're actually trying to mangle; if it's null, we're mangling the + guard variable for T. */ static void -maybe_check_abi_tags (tree t) +maybe_check_abi_tags (tree t, tree for_decl) { + if (DECL_ASSEMBLER_NAME_SET_P (t)) + return; + tree attr = lookup_attribute ("abi_tag", DECL_ATTRIBUTES (t)); tree oldtags = NULL_TREE; if (attr) oldtags = TREE_VALUE (attr); - check_abi_tags (t); + mangle_decl (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); + { + if (for_decl) + warning_at (DECL_SOURCE_LOCATION (for_decl), OPT_Wabi, + "the mangled name of %qD changes between " + "-fabi-version=%d and -fabi-version=%d", + for_decl, flag_abi_version, warn_abi_version); + else + 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 @@ -3971,15 +3988,7 @@ write_guarded_var_name (const tree variable) to the reference, not the temporary. */ write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4); else - { - /* 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); - } + write_name (variable, /*ignore_local_scope=*/0); } /* Return an identifier for the name of an initialization guard @@ -3988,6 +3997,8 @@ write_guarded_var_name (const tree variable) tree mangle_guard_variable (const tree variable) { + if (abi_version_at_least (10)) + maybe_check_abi_tags (variable); start_mangling (variable); write_string ("_ZGV"); write_guarded_var_name (variable); diff --git a/gcc/testsuite/g++.dg/abi/abi-tag16a.C b/gcc/testsuite/g++.dg/abi/abi-tag16a.C index b02e856..12fe312 100644 --- a/gcc/testsuite/g++.dg/abi/abi-tag16a.C +++ b/gcc/testsuite/g++.dg/abi/abi-tag16a.C @@ -1,4 +1,4 @@ -// { dg-options "-fabi-version=9 -Wabi" } +// { dg-options "-fabi-version=9" } // { dg-final { scan-assembler "_ZGVZN1N1FEvE4Name" } } namespace std { __extension__ inline namespace __cxx11 __attribute__((abi_tag("cxx11"))) { @@ -10,7 +10,7 @@ namespace std { namespace N { inline void F() { { - static std::String Name; // { dg-warning "mangled name" } + static std::String Name; } } void F2() { diff --git a/gcc/testsuite/g++.dg/abi/abi-tag18.C b/gcc/testsuite/g++.dg/abi/abi-tag18.C new file mode 100644 index 0000000..89ee737 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/abi-tag18.C @@ -0,0 +1,20 @@ +// { dg-options -Wabi=9 } +// { dg-final { scan-assembler "_Z1fB7__test1v" } } +// { dg-final { scan-assembler "_ZZ1fB7__test1vEN1T1gB7__test2Ev" } } +// { dg-final { scan-assembler "_ZZZ1fB7__test1vEN1T1gB7__test2EvE1x" } } +// { dg-final { scan-assembler "_ZGVZZ1fB7__test1vEN1T1gB7__test2EvE1x" } } + +struct X { ~X(); }; +inline namespace __test1 __attribute__((abi_tag)) { struct A1 { }; } +inline namespace __test2 __attribute__((abi_tag)) { struct A2 { }; } +inline A1 f() { + struct T { + A2 g() { // { dg-warning "mangled name" } + static X x; // { dg-warning "mangled name" } + } + }; + T().g(); +} +int main() { + f(); +} diff --git a/gcc/testsuite/g++.dg/abi/abi-tag18a.C b/gcc/testsuite/g++.dg/abi/abi-tag18a.C new file mode 100644 index 0000000..f65f629 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/abi-tag18a.C @@ -0,0 +1,20 @@ +// { dg-options -fabi-version=9 } +// { dg-final { scan-assembler "_Z1fB7__test1v" } } +// { dg-final { scan-assembler "_ZZ1fB7__test1vEN1T1gB7__test2Ev" } } +// { dg-final { scan-assembler "_ZZZ1fB7__test1vEN1T1gEvE1x" } } +// { dg-final { scan-assembler "_ZGVZZ1fvEN1T1gEvE1x" } } + +struct X { ~X(); }; +inline namespace __test1 __attribute__((abi_tag)) { struct A1 { }; } +inline namespace __test2 __attribute__((abi_tag)) { struct A2 { }; } +inline A1 f() { + struct T { + A2 g() { + static X x; + } + }; + T().g(); +} +int main() { + f(); +}