This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] DWARF array bounds missing from C++ array definitions
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Alexandre Oliva <oliva at adacore dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jason Merrill <jason at redhat dot com>, Cary Coutant <ccoutant at gmail dot com>
- Date: Tue, 1 Oct 2019 13:06:48 +0200
- Subject: Re: [PATCH] DWARF array bounds missing from C++ array definitions
- References: <orv9txvpdm.fsf@lxoliva.fsfla.org> <CAFiYyc2d4hCra6PFHEczhP5UJWvgToiDx21sm83NTpUt2=a3Ug@mail.gmail.com> <orr24lvja5.fsf@lxoliva.fsfla.org> <CAFiYyc15igYr7qD+4hQDJfL1UN3+x-QfUuFSCy7bH6keV=5YKA@mail.gmail.com> <ora7b9um4x.fsf@lxoliva.fsfla.org> <CAFiYyc22E8t25uQA2DxQCqTYZLf8tLY+gxX1iMU6V7w+UTmpYA@mail.gmail.com> <oro8z7x15x.fsf@lxoliva.fsfla.org> <CAFiYyc0-zsTBFNNmsdJ3FvcgEm6JwPXqeUq7wXVkn6ENSKyX-g@mail.gmail.com> <or36gclugf.fsf@lxoliva.fsfla.org>
On Tue, Oct 1, 2019 at 10:51 AM Alexandre Oliva <oliva@adacore.com> wrote:
>
> On Sep 26, 2019, Richard Biener <richard.guenther@gmail.com> wrote:
>
> > On Thu, Sep 26, 2019 at 4:05 AM Alexandre Oliva <oliva@adacore.com> wrote:
>
> > Heh, I don't have one - which usually makes me simply inline the
> > beast into the single caller :P
>
> > Maybe simply have_new_type_for_decl_with_old_die_p?
> > Or new_type_for_die_p?
>
> How about override_type_for_decl_p?
Also good.
OK for trunk (& branches I guess, it's a regression).
Thanks,
Richard.
>
> for gcc/ChangeLog
>
> * dwarf2out.c (override_type_for_decl_p): New.
> (gen_variable_die): Use it.
>
> for gcc/testsuite/ChangeLog
>
> * gcc.dg/debug/dwarf2/array-0.c: New.
> * gcc.dg/debug/dwarf2/array-1.c: New.
> * gcc.dg/debug/dwarf2/array-2.c: New.
> * gcc.dg/debug/dwarf2/array-3.c: New.
> * g++.dg/debug/dwarf2/array-0.C: New.
> * g++.dg/debug/dwarf2/array-1.C: New.
> * g++.dg/debug/dwarf2/array-2.C: New. Based on libstdc++-v3's
> src/c++98/pool_allocator.cc:__pool_alloc_base::_S_heap_size.
> * g++.dg/debug/dwarf2/array-3.C: New. Based on
> gcc's config/i386/i386-features.c:xlogue_layout::s_instances.
> * g++.dg/debug/dwarf2/array-4.C: New.
> ---
> gcc/dwarf2out.c | 32 ++++++++++++++++++++++++++-
> gcc/testsuite/g++.dg/debug/dwarf2/array-0.C | 13 +++++++++++
> gcc/testsuite/g++.dg/debug/dwarf2/array-1.C | 13 +++++++++++
> gcc/testsuite/g++.dg/debug/dwarf2/array-2.C | 15 +++++++++++++
> gcc/testsuite/g++.dg/debug/dwarf2/array-3.C | 20 +++++++++++++++++
> gcc/testsuite/g++.dg/debug/dwarf2/array-4.C | 16 ++++++++++++++
> gcc/testsuite/gcc.dg/debug/dwarf2/array-0.c | 10 ++++++++
> gcc/testsuite/gcc.dg/debug/dwarf2/array-1.c | 10 ++++++++
> gcc/testsuite/gcc.dg/debug/dwarf2/array-2.c | 8 +++++++
> gcc/testsuite/gcc.dg/debug/dwarf2/array-3.c | 8 +++++++
> 10 files changed, 144 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/array-0.C
> create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/array-1.C
> create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/array-2.C
> create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/array-3.C
> create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/array-4.C
> create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/array-0.c
> create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/array-1.c
> create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/array-2.c
> create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/array-3.c
>
> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
> index cec25fa5fa2b8..a29a200f19814 100644
> --- a/gcc/dwarf2out.c
> +++ b/gcc/dwarf2out.c
> @@ -23706,6 +23706,34 @@ local_function_static (tree decl)
> && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL;
> }
>
> +/* Return true iff DECL overrides (presumably completes) the type of
> + OLD_DIE within CONTEXT_DIE. */
> +
> +static bool
> +override_type_for_decl_p (tree decl, dw_die_ref old_die,
> + dw_die_ref context_die)
> +{
> + tree type = TREE_TYPE (decl);
> + int cv_quals;
> +
> + if (decl_by_reference_p (decl))
> + {
> + type = TREE_TYPE (type);
> + cv_quals = TYPE_UNQUALIFIED;
> + }
> + else
> + cv_quals = decl_quals (decl);
> +
> + dw_die_ref type_die = modified_type_die (type,
> + cv_quals | TYPE_QUALS (type),
> + false,
> + context_die);
> +
> + dw_die_ref old_type_die = get_AT_ref (old_die, DW_AT_type);
> +
> + return type_die != old_type_die;
> +}
> +
> /* Generate a DIE to represent a declared data object.
> Either DECL or ORIGIN must be non-null. */
>
> @@ -23958,7 +23986,9 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
> && !DECL_ABSTRACT_P (decl_or_origin)
> && variably_modified_type_p (TREE_TYPE (decl_or_origin),
> decl_function_context
> - (decl_or_origin))))
> + (decl_or_origin)))
> + || (old_die && specialization_p
> + && override_type_for_decl_p (decl_or_origin, old_die, context_die)))
> {
> tree type = TREE_TYPE (decl_or_origin);
>
> diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/array-0.C b/gcc/testsuite/g++.dg/debug/dwarf2/array-0.C
> new file mode 100644
> index 0000000000000..a3458bd0d32a4
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/debug/dwarf2/array-0.C
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf-2 -dA" } */
> +struct S
> +{
> + static int array[42];
> +};
> +
> +int S::array[42];
> +
> +/* Verify that we get only one DW_TAG_subrange_type with a
> + DW_AT_upper_bound. */
> +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */
> +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */
> diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/array-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/array-1.C
> new file mode 100644
> index 0000000000000..e8fd6f8ffea56
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/debug/dwarf2/array-1.C
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf-2 -dA" } */
> +struct S
> +{
> + static int array[];
> +};
> +
> +int S::array[42];
> +
> +/* Verify that we get two DW_TAG_subrange_type, only one of which with
> + a DW_AT_upper_bound. */
> +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 4 } } */
> +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */
> diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/array-2.C b/gcc/testsuite/g++.dg/debug/dwarf2/array-2.C
> new file mode 100644
> index 0000000000000..dd17812043898
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/debug/dwarf2/array-2.C
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf-2 -dA" } */
> +struct S
> +{
> + typedef int i_t;
> + static i_t array[42];
> +};
> +
> +int S::array[42];
> +
> +/* Verify that we get two DW_TAG_subrange_type (plus abbrev), and two
> + DW_AT_upper_bound, because a different symbolic name is used for
> + the array element type. */
> +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 3 } } */
> +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 2 } } */
> diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/array-3.C b/gcc/testsuite/g++.dg/debug/dwarf2/array-3.C
> new file mode 100644
> index 0000000000000..8db6133b76585
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/debug/dwarf2/array-3.C
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf-2 -dA" } */
> +struct S
> +{
> + S() {}
> + ~S() {}
> + static const S array[2];
> +};
> +
> +const S S::array[2] = { S(), S() };
> +
> +/* Verify that we get only one DW_TAG_subrange_type (plus the abbrev),
> + and one DW_AT_upper_bound (non-abbrev), because the array
> + definition loses the readonly wrapper for the array type because of
> + the dynamic initializers. The const types are 4: S, S*, int, and
> + S[4], plus the abbrev. A const version of S[4] doesn't make sense,
> + but we output it. */
> +/* { dg-final { scan-assembler-times " DW_TAG_const_type" 5 } } */
> +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */
> +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */
> diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/array-4.C b/gcc/testsuite/g++.dg/debug/dwarf2/array-4.C
> new file mode 100644
> index 0000000000000..6b3f546c1b583
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/debug/dwarf2/array-4.C
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf-2 -dA" } */
> +struct S
> +{
> + S() {}
> + ~S() {}
> +};
> +
> +const S array[2] = { S(), S() };
> +
> +/* Like array-3, but with a non-member array without a separate
> + declaration, to check that we don't issue the nonsensical
> + DW_TAG_const_type used by the member array declaration there. */
> +/* { dg-final { scan-assembler-times " DW_TAG_const_type" 4 } } */
> +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */
> +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */
> diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/array-0.c b/gcc/testsuite/gcc.dg/debug/dwarf2/array-0.c
> new file mode 100644
> index 0000000000000..b06392e04a2db
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/array-0.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf-2 -dA" } */
> +extern int array[42];
> +
> +int array[42];
> +
> +/* Verify that we get only one DW_TAG_subtrange_type (plus abbrev),
> + with a DW_AT_upper_bound. */
> +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */
> +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */
> diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/array-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/array-1.c
> new file mode 100644
> index 0000000000000..ad8f466ef08ad
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/array-1.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf-2 -dA" } */
> +extern int array[];
> +
> +int array[42];
> +
> +/* Verify that we get two DW_TAG_subtrange_type (each with an abbrev),
> + but only one DW_AT_upper_bound. */
> +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 4 } } */
> +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */
> diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/array-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/array-2.c
> new file mode 100644
> index 0000000000000..5d1606f0889fc
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/array-2.c
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf-2 -dA" } */
> +int array[42];
> +
> +/* Verify that we get only one DW_TAG_subtrange_type (plus abbrev)
> + with DW_AT_upper_bound. */
> +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */
> +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */
> diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/array-3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/array-3.c
> new file mode 100644
> index 0000000000000..077a62ef9a3bf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/array-3.c
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +/* { dg-options "-gdwarf-2 -dA" } */
> +int array[] = { 0, 1, 2 };
> +
> +/* Verify that we get only one DW_TAG_subtrange_type (plus abbrev)
> + with DW_AT_upper_bound. */
> +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */
> +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */
>
>
> --
> Alexandre Oliva, freedom fighter he/him https://FSFLA.org/blogs/lxo
> Be the change, be Free! FSF VP & FSF Latin America board member
> GNU Toolchain Engineer Free Software Evangelist
> Hay que enGNUrecerse, pero sin perder la terGNUra jamás - Che GNUevara