On Sat, Oct 11, 2025 at 3:21 AM David Faust <[email protected]> wrote:
>
> The check in gen_btf_tag_dies which asserted that if the target DIE
> already had an annotation then it must be the same as the one we are
> attempting to add was too strict.  It is valid for multiple declarations
> of the same object to appear with different decl_tags, in which case the
> tags are accumulated in the DECL_ATTRIBUTES, but the existing tag may
> not be the same as the one being added.  This was not handled correctly
> and led to the ICE reported in the PR.
>
> The more accurate requirement for consistency is that if there is an
> existing chain of annotations, then it is a sub-chain of the one we are
> adding in the current pass.  This patch fixes gen_btf_tag_dies to use
> the more accurate check and properly handle the case in the PR.
>
> Bootstrapped and tested on x86_64-linux-gnu.
>
> OK for trunk?
> Thanks
>
>         PR debug/122248
>
> gcc/
>
>         * dwarf2out.cc (gen_btf_tag_dies): Handle repeated declarations
>         of the same object with different decl_tags and improve accuracy
>         of the consistency check under flag_checking.
>
> gcc/testsuite/
>
>         * gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c: New.
>         * gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c: New.
>         * gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c: New.
> ---
>  gcc/dwarf2out.cc                              | 27 +++++++++++---
>  .../debug/dwarf2/dwarf-btf-decl-tag-4.c       | 28 +++++++++++++++
>  .../debug/dwarf2/dwarf-btf-decl-tag-5.c       | 35 +++++++++++++++++++
>  .../debug/dwarf2/dwarf-btf-decl-tag-6.c       | 24 +++++++++++++
>  4 files changed, 109 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c
>
> diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
> index a817c69c95a..8fe6e3321e1 100644
> --- a/gcc/dwarf2out.cc
> +++ b/gcc/dwarf2out.cc
> @@ -13843,13 +13843,30 @@ gen_btf_tag_dies (tree attr, dw_die_ref die)
>    if (die)
>      {
>        /* Add AT_GNU_annotation referring to the annotation DIE.
> -        It may have already been added, some global declarations are 
> processed
> -        twice, but if so it must be the same or we have a bug.  */
> +        There may be an existing annotation chain, as in the case of global
> +        decls which may can processed (and declared) multiple times.
> +        Each time a global decl is processed it may have additional
> +        decl_tags, but the set should never shrink.  */
>        dw_die_ref existing = get_AT_ref (die, DW_AT_GNU_annotation);
>        if (existing)
> -       gcc_checking_assert (existing == tag_die);
> -      else
> -       add_AT_die_ref (die, DW_AT_GNU_annotation, tag_die);
> +       {
> +         if (flag_checking)
> +           {
> +             /* If there is an existing annotation chain, then it must be a
> +                sub-chain of this one, i.e. its head must be somewhere in the
> +                chain from tag_die.  Otherwise we may have a bug.  */

A bug in the DWARF implementation or in the users use of attributes?
The latter should not be diagnosed with an assert.

> +             dw_die_ref d = tag_die;
> +             while (d && d != existing)
> +               d = get_AT_ref (die, DW_AT_GNU_annotation);
> +
> +             gcc_assert (d);
> +           }
> +
> +         /* Remove the existing annotation and replace it with the new.  */
> +         remove_AT (die, DW_AT_GNU_annotation);
> +       }
> +
> +      add_AT_die_ref (die, DW_AT_GNU_annotation, tag_die);
>      }
>
>    return tag_die;
> diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c 
> b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c
> new file mode 100644
> index 00000000000..6fdcdc6e864
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c
> @@ -0,0 +1,28 @@
> +/* Test DWARF generation for decl_tags on global decls appearing multiple
> +   times with different decl_tags.  PR122248.  */
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf -dA" } */
> +
> +#define __tag1 __attribute__((btf_decl_tag ("tag1")))
> +#define __tag2 __attribute__((btf_decl_tag ("tag2")))
> +#define __tag3 __attribute__((btf_decl_tag ("tag3")))
> +#define __tag4 __attribute__((btf_decl_tag ("tag4")))
> +
> +int foo __tag1;
> +int foo __tag2;
> +
> +/* Result: foo has __tag1 and __tag2.  */
> +
> +int bar __tag3;
> +int bar;
> +
> +/* Result: bar has __tag3.  */
> +
> +int baz;
> +int baz __tag4;
> +
> +/* Result: baz has __tag4.  */
> +
> +/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) 
> DW_TAG_GNU_annotation" 4 } } */
> +/* { dg-final { scan-assembler-times " DW_AT_GNU_annotation" 4 } } */
> +
> diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c 
> b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c
> new file mode 100644
> index 00000000000..c7cb60ca986
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c
> @@ -0,0 +1,35 @@
> +/* Test DWARF generation for decl_tags on global decls appearing multiple
> +   times with different decl_tags.  PR122248.  */
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf -dA" } */
> +
> +#define __tag1 __attribute__((btf_decl_tag ("tag1")))
> +#define __tag2 __attribute__((btf_decl_tag ("tag2")))
> +#define __tag3 __attribute__((btf_decl_tag ("tag3")))
> +
> +struct S
> +{
> +  int x;
> +  char c;
> +};
> +
> +extern struct S foo __tag1;
> +struct S foo __tag2;
> +
> +/* Result: non-completing variable DIE for 'foo' has tag1, and the
> +   completing DIE (with AT_specification) for 'foo' has tag2 -> tag1.  */
> +
> +extern int a __tag3;
> +int a;
> +
> +/* Result: non-completing variable DIE for a has tag3, and the
> +   completing DIE (with AT_specification) for 'a' also refers to tag3.  */
> +
> +/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) 
> DW_TAG_GNU_annotation" 3 } } */
> +
> +/* 5 AT_GNU annotations:
> +   - foo -> tag1
> +   - foo -> tag2 -> tag1
> +   - a -> tag3
> +   - a -> tag3 */
> +/* { dg-final { scan-assembler-times " DW_AT_GNU_annotation" 5 } } */
> diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c 
> b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c
> new file mode 100644
> index 00000000000..dd89d1142b9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c
> @@ -0,0 +1,24 @@
> +/* Test DWARF generation for decl_tags on global decls appearing multiple
> +   times with different decl_tags.  PR122248.  */
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf -dA" } */
> +
> +#define __tag1 __attribute__((btf_decl_tag ("tag1")))
> +#define __tag2 __attribute__((btf_decl_tag ("tag2")))
> +#define __tag3 __attribute__((btf_decl_tag ("tag3")))
> +
> +__tag1
> +extern int
> +do_thing (int);
> +
> +__tag2
> +__tag3
> +int
> +do_thing (int x)
> +{
> +  return x * x;
> +}
> +
> +/* Result: do_thing has all 3 tags.  */
> +/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) 
> DW_TAG_GNU_annotation" 3 } } */
> +/* { dg-final { scan-assembler-times " DW_AT_GNU_annotation" 3 } } */
> --
> 2.51.0
>

Reply via email to