From 328eae1cb4cca4903f4b6de3bf56c4e59fdbdeae Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 29 Aug 2016 12:42:57 -0400 Subject: [PATCH] PR c++/77379 - ABI tag on thunk * mangle.c (maybe_check_abi_tags): Add version parm, handle thunks. (mangle_thunk): Add thunk parameter. * method.c (finish_thunk): Pass it. * cp-tree.h: Declare it. From-SVN: r239830 --- gcc/cp/ChangeLog | 8 ++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/mangle.c | 18 ++++++++++---- gcc/cp/method.c | 2 +- gcc/testsuite/g++.dg/abi/abi-tag23.C | 35 +++++++++++++++++++++++++++ gcc/testsuite/g++.dg/abi/abi-tag23a.C | 35 +++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/abi-tag23.C create mode 100644 gcc/testsuite/g++.dg/abi/abi-tag23a.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e8e2e038b43..55651bc83b0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2016-08-29 Jason Merrill + + PR c++/77379 + * mangle.c (maybe_check_abi_tags): Add version parm, handle thunks. + (mangle_thunk): Add thunk parameter. + * method.c (finish_thunk): Pass it. + * cp-tree.h: Declare it. + 2016-08-15 Jason Merrill Avoid calling a trivial default constructor. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 72a128d90dd..5bcb98b9756 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6802,7 +6802,7 @@ extern tree mangle_typeinfo_string_for_type (tree); extern tree mangle_vtbl_for_type (tree); extern tree mangle_vtt_for_type (tree); extern tree mangle_ctor_vtbl_for_type (tree, tree); -extern tree mangle_thunk (tree, int, tree, tree); +extern tree mangle_thunk (tree, int, tree, tree, tree); extern tree mangle_conv_op_name_for_type (tree); extern tree mangle_guard_variable (tree); extern tree mangle_tls_init_fn (tree); diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index d8b5c45577f..d34743c9c68 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -231,7 +231,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); +static void maybe_check_abi_tags (tree, tree = NULL_TREE, int = 10); static bool equal_abi_tags (tree, tree); /* Control functions. */ @@ -4024,10 +4024,13 @@ mangle_call_offset (const tree fixed_offset, const tree virtual_offset) tree mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset, - tree virtual_offset) + tree virtual_offset, tree thunk) { tree result; + if (abi_version_at_least (11)) + maybe_check_abi_tags (fn_decl, thunk, 11); + start_mangling (fn_decl); write_string ("_Z"); @@ -4142,7 +4145,7 @@ mangle_conv_op_name_for_type (const tree type) guard variable for T. */ static void -maybe_check_abi_tags (tree t, tree for_decl) +maybe_check_abi_tags (tree t, tree for_decl, int ver) { if (DECL_ASSEMBLER_NAME_SET_P (t)) return; @@ -4153,9 +4156,14 @@ maybe_check_abi_tags (tree t, tree for_decl) tree newtags = get_abi_tags (t); if (newtags && newtags != oldtags - && abi_version_crosses (10)) + && abi_version_crosses (ver)) { - if (for_decl) + if (for_decl && DECL_THUNK_P (for_decl)) + warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi, + "the mangled name of a thunk for %qD changes between " + "-fabi-version=%d and -fabi-version=%d", + t, flag_abi_version, warn_abi_version); + else 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", diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 75342ae5d28..957ea391383 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -169,7 +169,7 @@ finish_thunk (tree thunk) virtual_offset = BINFO_VPTR_FIELD (virtual_offset); function = THUNK_TARGET (thunk); name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk), - fixed_offset, virtual_offset); + fixed_offset, virtual_offset, thunk); /* We can end up with declarations of (logically) different covariant thunks, that do identical adjustments. The two thunks diff --git a/gcc/testsuite/g++.dg/abi/abi-tag23.C b/gcc/testsuite/g++.dg/abi/abi-tag23.C new file mode 100644 index 00000000000..5e310a4a42a --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/abi-tag23.C @@ -0,0 +1,35 @@ +// PR c++/77379 +// { dg-options "-fabi-version=0 -Wabi=10" } + +struct __attribute ((abi_tag ("bar"))) string { }; + +struct Mother +{ + virtual ~Mother() {}; + int bar; +}; + +struct Father +{ + virtual string get_foo() = 0; +}; + +class Derived: + public Mother, + public Father +{ +public: + string get_foo(); // { dg-warning "mangled name" } +}; + +struct Final: + public Derived +{ +}; + +int main() +{ + Final().get_foo(); +} + +// { dg-final { scan-assembler "_ZThn16_N7Derived7get_fooB3barEv" } } diff --git a/gcc/testsuite/g++.dg/abi/abi-tag23a.C b/gcc/testsuite/g++.dg/abi/abi-tag23a.C new file mode 100644 index 00000000000..72aa037f0b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/abi-tag23a.C @@ -0,0 +1,35 @@ +// PR c++/77379 +// { dg-options -fabi-version=10 } + +struct __attribute ((abi_tag ("bar"))) string { }; + +struct Mother +{ + virtual ~Mother() {}; + int bar; +}; + +struct Father +{ + virtual string get_foo() = 0; +}; + +class Derived: + public Mother, + public Father +{ +public: + string get_foo(); +}; + +struct Final: + public Derived +{ +}; + +int main() +{ + Final().get_foo(); +} + +// { dg-final { scan-assembler "_ZThn16_N7Derived7get_fooEv" } } -- 2.30.2