On Sep 26, 2019, Richard Biener <richard.guent...@gmail.com> wrote: > On Thu, Sep 26, 2019 at 4:05 AM Alexandre Oliva <ol...@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? 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