commit 02ad075e2058c6c4f6cf05606653981c5efb4d0d Author: Jason Merrill Date: Wed Mar 31 17:48:50 2021 -0400 c++: Add ABI version for PR98481 fix The PR98481 fix corrects an ABI regression in GCC 10, but we don't want to introduce an ABI change in the middle of the GCC 10 cycle. This patch introduces ABI v15 for the fix, which will be available but not default in GCC 10.3; the broken behavior remains in ABI v14. Compatibility aliases will not be generated for this change. gcc/ChangeLog: PR c++/98481 * common.opt: Document v15 and v16. gcc/c-family/ChangeLog: PR c++/98481 * c-opts.c (c_common_post_options): Bump latest_abi_version. gcc/cp/ChangeLog: PR c++/98481 * mangle.c (write_expression): Adjust. * class.c (find_abi_tags_r): Disable PR98481 fix for ABI v14. (mark_abi_tags_r): Likewise. gcc/testsuite/ChangeLog: PR c++/98481 * g++.dg/abi/abi-tag24a.C: New test. * g++.dg/abi/macro0.C: Adjust expected value. diff --git a/gcc/common.opt b/gcc/common.opt index c75dd36843e..a75b44ee47e 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -960,7 +960,11 @@ Driver Undocumented ; 14: Corrects the mangling of nullptr expression. ; Default in G++ 10. ; -; 15: Changes the mangling of __alignof__ to be distinct from that of alignof. +; 15: Corrects G++ 10 ABI tag regression [PR98481]. +; Available, but not default, in G++ 10.3. +; +; 16: Changes the mangling of __alignof__ to be distinct from that of alignof. +; Adds missing 'on' in mangling of operator names in some cases. ; Default in G++ 11. ; ; Additional positive integers will be assigned as new versions of diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index bd15b9cd902..89e05a4c551 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -965,7 +965,7 @@ c_common_post_options (const char **pfilename) /* Change flag_abi_version to be the actual current ABI level, for the benefit of c_cpp_builtins, and to make comparison simpler. */ - const int latest_abi_version = 15; + const int latest_abi_version = 16; /* Generate compatibility aliases for ABI v11 (7.1) by default. */ const int abi_compat_default = 11; diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 856e81e3d1a..4bffec4a707 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1494,8 +1494,8 @@ mark_or_check_tags (tree t, tree *tp, abi_tag_data *p, bool val) static tree find_abi_tags_r (tree *tp, int *walk_subtrees, void *data) { - if (TYPE_P (*tp) && *walk_subtrees == 1) - /* Tell cp_walk_subtrees to look though typedefs. */ + if (TYPE_P (*tp) && *walk_subtrees == 1 && flag_abi_version != 14) + /* Tell cp_walk_subtrees to look though typedefs. [PR98481] */ *walk_subtrees = 2; if (!OVERLOAD_TYPE_P (*tp)) @@ -1518,7 +1518,7 @@ find_abi_tags_r (tree *tp, int *walk_subtrees, void *data) static tree mark_abi_tags_r (tree *tp, int *walk_subtrees, void *data) { - if (TYPE_P (*tp) && *walk_subtrees == 1) + if (TYPE_P (*tp) && *walk_subtrees == 1 && flag_abi_version != 14) /* Tell cp_walk_subtrees to look though typedefs. */ *walk_subtrees = 2; diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 57ce9a6710f..6c111342b97 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -3119,9 +3119,9 @@ write_expression (tree expr) { if (!ALIGNOF_EXPR_STD_P (expr)) { - if (abi_warn_or_compat_version_crosses (15)) + if (abi_warn_or_compat_version_crosses (16)) G.need_abi_warning = true; - if (abi_version_at_least (15)) + if (abi_version_at_least (16)) { /* We used to mangle __alignof__ like alignof. */ write_string ("u11__alignof__"); @@ -3350,9 +3350,9 @@ write_expression (tree expr) tree name = dependent_name (expr); if (IDENTIFIER_ANY_OP_P (name)) { - if (abi_version_at_least (15)) + if (abi_version_at_least (16)) write_string ("on"); - if (abi_warn_or_compat_version_crosses (15)) + if (abi_warn_or_compat_version_crosses (16)) G.need_abi_warning = 1; } write_unqualified_id (name); diff --git a/gcc/testsuite/g++.dg/abi/abi-tag24a.C b/gcc/testsuite/g++.dg/abi/abi-tag24a.C new file mode 100644 index 00000000000..83f930dfdde --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/abi-tag24a.C @@ -0,0 +1,18 @@ +// PR c++/98481 +// { dg-do compile { target c++11 } } +// { dg-additional-options -fabi-version=14 } +inline namespace N __attribute ((__abi_tag__ ("myabi"))) +{ + struct A {}; +} +template +struct B { typedef int size_type; }; +struct S1 { B::size_type foo () const { return 1; } }; +struct S2 { B::size_type foo () const; }; +int S2::foo () const { return 2; } +int (S1::*f1) () const = &S1::foo; +int (S2::*f2) () const = &S2::foo; + +// { dg-final { scan-assembler-not "_ZNK2S13fooEv" } } +// { dg-final { scan-assembler "_ZNK2S23fooEv" } } +// { dg-final { scan-assembler "_ZNK2S13fooB5myabiEv" } } diff --git a/gcc/testsuite/g++.dg/abi/macro0.C b/gcc/testsuite/g++.dg/abi/macro0.C index 7c3c17051ed..f25f291dba6 100644 --- a/gcc/testsuite/g++.dg/abi/macro0.C +++ b/gcc/testsuite/g++.dg/abi/macro0.C @@ -1,6 +1,6 @@ // This testcase will need to be kept in sync with c_common_post_options. // { dg-options "-fabi-version=0" } -#if __GXX_ABI_VERSION != 1015 +#if __GXX_ABI_VERSION != 1016 #error "Incorrect value of __GXX_ABI_VERSION" #endif