public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: Jason Merrill <jason@redhat.com>
Cc: Richard Biener <rguenther@suse.de>, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c++, abi: Fix abi_tag attribute handling [PR98481]
Date: Thu, 1 Apr 2021 07:47:29 +0200	[thread overview]
Message-ID: <20210401054729.GV1179226@tucnak> (raw)
In-Reply-To: <03eaf1db-d40d-5aa7-fc34-478bb97c0efa@redhat.com>

On Thu, Apr 01, 2021 at 12:52:20AM -0400, Jason Merrill wrote:
> On 1/8/21 2:29 PM, Jakub Jelinek wrote:
> > On Fri, Jan 08, 2021 at 02:22:59PM -0500, Jason Merrill wrote:
> > > I like the idea to use *walk_subtrees to distinguish between walking
> > > syntactic subtrees and walking type-identity subtrees.  But it should be
> > > more general; how does this look to you?
> > 
> > LGTM, thanks.
> 
> As discussed on IRC, we probably want to fix this in GCC 10 as well, but not
> by default.  The first patch adds ABI v15 and fixes the bug for !v14, so
> -fabi-version=0 has the fix, but the default behavior does not.  The second
> patch adds ABI v15 on trunk.
> 
> It would be nice to make -Wabi/-fabi-compat-version handle this case, but
> that would require a bunch of new code unsuitable for this point in the
> process.
> 
> Does this make sense to you?

LGTM, thanks.

> commit 123f254cce416a4d50445465b88af6d8e754dc5e
> Author: Jakub Jelinek <jakub@redhat.com>
> Date:   Thu Jan 7 17:47:18 2021 +0100
> 
>     c++, abi: Fix abi_tag attribute handling [PR98481]
>     
>     In GCC10 cp_walk_subtrees has been changed to walk template arguments.
>     As the following testcase, that changed the mangling of some functions.
>     I believe the previous behavior that find_abi_tags_r doesn't recurse into
>     template args has been the correct one, but setting *walk_subtrees = 0
>     for the types and handling the types subtree walking manually in
>     find_abi_tags_r looks too hard, there are a lot of subtrees and details what
>     should and shouldn't be walked, both in tree.c (walk_type_fields there,
>     which is static) and in cp_walk_subtrees itself.
>     
>     The following patch abuses the fact that *walk_subtrees is an int to
>     tell cp_walk_subtrees it shouldn't walk the template args.
>     
>     But we don't want to introduce an ABI change in the middle of the GCC 10
>     cycle, so the GCC 10 version of this patch introduces ABI v15 for the fix,
>     which will be available but not default in GCC 10.3.
>     
>     Co-authored-by: Jason Merrill <jason@redhat.com>
>     
>     gcc/cp/ChangeLog:
>     
>             PR c++/98481
>             * class.c (find_abi_tags_r): Set *walk_subtrees to 2 instead of 1
>             for types.
>             (mark_abi_tags_r): Likewise.
>             * tree.c (cp_walk_subtrees): If *walk_subtrees_p is 2, look through
>             typedefs.
>     
>     gcc/testsuite/ChangeLog:
>     
>             PR c++/98481
>             * g++.dg/abi/abi-tag24.C: New test.
>             * g++.dg/abi/abi-tag24a.C: New test.
>             * g++.dg/abi/macro0.C: Adjust expected value.
>     
>     gcc/ChangeLog:
>     
>             PR c++/98481
>             * common.opt (fabi-version): Default to 14.
>     
>     gcc/c-family/ChangeLog:
>     
>             PR c++/98481
>             * c-opts.c (c_common_post_options): Bump latest_abi_version.
> 
> diff --git a/gcc/common.opt b/gcc/common.opt
> index 9cc47b16cac..ec5235c3a41 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -956,10 +956,13 @@ Driver Undocumented
>  ; 14: Corrects the mangling of nullptr expression.
>  ;     Default in G++ 10.
>  ;
> +; 15: Corrects G++ 10 ABI tag regression [PR98481].
> +;     Available, but not default, in G++ 10.3.
> +;
>  ; Additional positive integers will be assigned as new versions of
>  ; the ABI become the default version of the ABI.
>  fabi-version=
> -Common Joined RejectNegative UInteger Var(flag_abi_version) Init(0)
> +Common Joined RejectNegative UInteger Var(flag_abi_version) Init(14)
>  The version of the C++ ABI in use.
>  
>  faggressive-loop-optimizations
> diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
> index 58ba0948e79..c51d6d34726 100644
> --- a/gcc/c-family/c-opts.c
> +++ b/gcc/c-family/c-opts.c
> @@ -943,7 +943,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 = 14;
> +  const int latest_abi_version = 15;
>    /* 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 ed8f9527929..c0101130ba3 100644
> --- a/gcc/cp/class.c
> +++ b/gcc/cp/class.c
> @@ -1450,6 +1450,10 @@ 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 && flag_abi_version != 14)
> +    /* Tell cp_walk_subtrees to look though typedefs. [PR98481] */
> +    *walk_subtrees = 2;
> +
>    if (!OVERLOAD_TYPE_P (*tp))
>      return NULL_TREE;
>  
> @@ -1470,6 +1474,10 @@ 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 && flag_abi_version != 14)
> +    /* Tell cp_walk_subtrees to look though typedefs.  */
> +    *walk_subtrees = 2;
> +
>    if (!OVERLOAD_TYPE_P (*tp))
>      return NULL_TREE;
>  
> diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
> index b36ca4eddc0..10b818d1370 100644
> --- a/gcc/cp/tree.c
> +++ b/gcc/cp/tree.c
> @@ -5055,8 +5055,18 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>    while (0)
>  
>    if (TYPE_P (*tp))
> -    /* Walk into template args without looking through typedefs.  */
> -    if (tree ti = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (*tp))
> +    /* If *WALK_SUBTREES_P is 1, we're interested in the syntactic form of
> +       the argument, so don't look through typedefs, but do walk into
> +       template arguments for alias templates (and non-typedefed classes).
> +
> +       If *WALK_SUBTREES_P > 1, we're interested in type identity or
> +       equivalence, so look through typedefs, ignoring template arguments for
> +       alias templates, and walk into template args of classes.
> +
> +       See find_abi_tags_r for an example of setting *WALK_SUBTREES_P to 2
> +       when that's the behavior the walk_tree_fn wants.  */
> +    if (tree ti = (*walk_subtrees_p > 1 ? TYPE_TEMPLATE_INFO (*tp)
> +		   : TYPE_TEMPLATE_INFO_MAYBE_ALIAS (*tp)))
>        WALK_SUBTREE (TI_ARGS (ti));
>  
>    /* Not one of the easy cases.  We must explicitly go through the
> diff --git a/gcc/testsuite/g++.dg/abi/abi-tag24.C b/gcc/testsuite/g++.dg/abi/abi-tag24.C
> new file mode 100644
> index 00000000000..2c5c542bfcd
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/abi/abi-tag24.C
> @@ -0,0 +1,18 @@
> +// PR c++/98481
> +// { dg-do compile { target c++11 } }
> +// { dg-additional-options -fabi-version=0 }
> +inline namespace N __attribute ((__abi_tag__ ("myabi")))
> +{
> +  struct A {};
> +}
> +template <typename T>
> +struct B { typedef int size_type; };
> +struct S1 { B<A>::size_type foo () const { return 1; } };
> +struct S2 { B<A>::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 "_ZNK2S13fooEv" } }
> +// { dg-final { scan-assembler "_ZNK2S23fooEv" } }
> +// { dg-final { scan-assembler-not "_ZNK2S13fooB5myabiEv" } }
> 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 <typename T>
> +struct B { typedef int size_type; };
> +struct S1 { B<A>::size_type foo () const { return 1; } };
> +struct S2 { B<A>::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 08106004c4d..7c3c17051ed 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 != 1014
> +#if __GXX_ABI_VERSION != 1015
>  #error "Incorrect value of __GXX_ABI_VERSION"
>  #endif

> commit 02ad075e2058c6c4f6cf05606653981c5efb4d0d
> Author: Jason Merrill <jason@redhat.com>
> 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 <typename T>
> +struct B { typedef int size_type; };
> +struct S1 { B<A>::size_type foo () const { return 1; } };
> +struct S2 { B<A>::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


	Jakub


  reply	other threads:[~2021-04-01  5:47 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-07 16:47 Jakub Jelinek
2021-01-08 19:22 ` Jason Merrill
2021-01-08 19:29   ` Jakub Jelinek
2021-04-01  4:52     ` Jason Merrill
2021-04-01  5:47       ` Jakub Jelinek [this message]
2021-04-01  7:56         ` Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210401054729.GV1179226@tucnak \
    --to=jakub@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    --cc=rguenther@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).