On Thu, 13 Sep 2018, Tom de Vries wrote: > On 9/4/18 5:59 PM, Tom de Vries wrote: > > [ Adding Jason as addressee ] > > > > On 08/28/2018 08:20 PM, Omar Sandoval wrote: > >> On Fri, Aug 17, 2018 at 12:16:07AM -0700, Omar Sandoval wrote: > >>> On Thu, Aug 16, 2018 at 11:54:53PM -0700, Omar Sandoval wrote: > >>>> On Thu, Aug 16, 2018 at 10:27:48PM -0700, Andrew Pinski wrote: > >>>>> On Thu, Aug 16, 2018 at 9:29 PM Omar Sandoval <osan...@osandov.com> > >>>>> wrote: > >>>>>> Hi, > >>>>>> > >>>>>> This fixes the issue that it is impossible to distinguish a > >>>>>> zero-length array > >>>>>> type from a flexible array type given the DWARF produced by GCC (which > >>>>>> I > >>>>>> reported here [1]). We do so by adding a DW_AT_count attribute with a > >>>>>> value of > >>>>>> zero only for zero-length arrays (this is what clang does in this > >>>>>> case, too). > >>>>>> > >>>>>> 1: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86985 > >>>>>> > >>>>>> The reproducer from the PR now produces the expected output: > >>>>>> > >>>>>> $ ~/gcc-build/gcc/xgcc -B ~/gcc-build/gcc -g -c zero_length.c > >>>>>> $ ~/gcc-build/gcc/xgcc -B ~/gcc-build/gcc -g -c flexible.c > >>>>>> $ gdb -batch -ex 'ptype baz' zero_length.o > >>>>>> type = struct { > >>>>>> int foo; > >>>>>> int bar[0]; > >>>>>> } > >>>>>> $ gdb -batch -ex 'ptype baz' flexible.o > >>>>>> type = struct { > >>>>>> int foo; > >>>>>> int bar[]; > >>>>>> } > >>>>>> > >>>>>> This was bootstrapped and tested on x86_64-pc-linux-gnu. > >>>>>> > >>>>>> I don't have commit rights (first time contributor), so if this change > >>>>>> is okay > >>>>>> could it please be applied? > >>> [snip] > >>> > >>> Here's the patch with the is_c () helper instead. > >>> > >>> 2018-08-17 Omar Sandoval <osan...@osandov.com> > >>> > > I've added the PR number here. > > > >>> * dwarf2out.c (is_c): New. > >>> (add_subscript_info): Add DW_AT_count of 0 for C zero-length arrays. > >>> > >>> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c > >>> index 5a74131d332..189f9bb381f 100644 > >>> --- a/gcc/dwarf2out.c > >>> +++ b/gcc/dwarf2out.c > >>> @@ -3671,6 +3671,7 @@ static const char *get_AT_string (dw_die_ref, enum > >>> dwarf_attribute); > >>> static int get_AT_flag (dw_die_ref, enum dwarf_attribute); > >>> static unsigned get_AT_unsigned (dw_die_ref, enum dwarf_attribute); > >>> static inline dw_die_ref get_AT_ref (dw_die_ref, enum dwarf_attribute); > >>> +static bool is_c (void); > >>> static bool is_cxx (void); > >>> static bool is_cxx (const_tree); > >>> static bool is_fortran (void); > >>> @@ -5434,6 +5435,19 @@ get_AT_file (dw_die_ref die, enum dwarf_attribute > >>> attr_kind) > >>> return a ? AT_file (a) : NULL; > >>> } > >>> > >>> +/* Return TRUE if the language is C. */ > >>> + > >>> +static inline bool > >>> +is_c (void) > >>> +{ > >>> + unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language); > >>> + > >>> + return (lang == DW_LANG_C || lang == DW_LANG_C89 || lang == DW_LANG_C99 > >>> + || lang == DW_LANG_C11 || lang == DW_LANG_ObjC); > >>> + > >>> + > >>> +} > >>> + > >>> /* Return TRUE if the language is C++. */ > >>> > >>> static inline bool > >>> @@ -20918,12 +20932,24 @@ add_subscript_info (dw_die_ref type_die, tree > >>> type, bool collapse_p) > >>> dimension arr(N:*) > >>> Since the debugger is definitely going to need to know N > >>> to produce useful results, go ahead and output the lower > >>> - bound solo, and hope the debugger can cope. */ > >>> + bound solo, and hope the debugger can cope. > >>> + > >>> + For C and C++, if upper is NULL, this may be a zero-length array > >>> + or a flexible array; we'd like to be able to distinguish between > >>> + the two. Set DW_AT_count to 0 for the former. TYPE_SIZE is NULL > >>> + for the latter. */ > >>> > > I found inserting this comment here confusing, I've moved it down and > > shortened it. > > > >>> if (!get_AT (subrange_die, DW_AT_lower_bound)) > >>> add_bound_info (subrange_die, DW_AT_lower_bound, lower, NULL); > >>> - if (upper && !get_AT (subrange_die, DW_AT_upper_bound)) > >>> - add_bound_info (subrange_die, DW_AT_upper_bound, upper, NULL); > >>> + if (!get_AT (subrange_die, DW_AT_upper_bound) > >>> + && !get_AT (subrange_die, DW_AT_count)) > >>> + { > >>> + if (upper) > >>> + add_bound_info (subrange_die, DW_AT_upper_bound, upper, NULL); > >>> + else if ((is_c () || is_cxx ()) && TYPE_SIZE (type)) > >>> + add_bound_info (subrange_die, DW_AT_count, > >>> + build_int_cst (TREE_TYPE (lower), 0), NULL); > >>> + } > >>> } > >>> > >>> /* Otherwise we have an array type with an unspecified length. The > >> Ping. Does this version look okay for trunk? > >> > > Looks ok to me (but I can't approve). > > > > Also, I've added a testcase. > > > > OK for trunk? > > > > Ping. > > Thanks, > - Tom > > > > > > 0001-debug-DWARF-add-DW_AT_count-to-zero-length-arrays.patch > > > > [debug] DWARF: add DW_AT_count to zero-length arrays > > > > 2018-09-04 Omar Sandoval <osan...@osandov.com> > > Tom de Vries <tdevr...@suse.de> > > > > PR debug/86985 > > * dwarf2out.c (is_c): New function. > > (add_subscript_info): Add DW_AT_count of 0 for C zero-length arrays. > > > > * gcc.dg/guality/zero-length-array.c: New test. > > > > --- > > gcc/dwarf2out.c | 26 > > ++++++++++++++++++++++-- > > gcc/testsuite/gcc.dg/guality/zero-length-array.c | 21 +++++++++++++++++++ > > 2 files changed, 45 insertions(+), 2 deletions(-) > > > > diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c > > index 77317ed2575..58c3906cdbf 100644 > > --- a/gcc/dwarf2out.c > > +++ b/gcc/dwarf2out.c > > @@ -3679,6 +3679,7 @@ static const char *get_AT_string (dw_die_ref, enum > > dwarf_attribute); > > static int get_AT_flag (dw_die_ref, enum dwarf_attribute); > > static unsigned get_AT_unsigned (dw_die_ref, enum dwarf_attribute); > > static inline dw_die_ref get_AT_ref (dw_die_ref, enum dwarf_attribute); > > +static bool is_c (void); > > static bool is_cxx (void); > > static bool is_cxx (const_tree); > > static bool is_fortran (void); > > @@ -5442,6 +5443,19 @@ get_AT_file (dw_die_ref die, enum dwarf_attribute > > attr_kind) > > return a ? AT_file (a) : NULL; > > } > > > > +/* Return TRUE if the language is C. */ > > + > > +static inline bool > > +is_c (void) > > +{ > > + unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language); > > + > > + return (lang == DW_LANG_C || lang == DW_LANG_C89 || lang == DW_LANG_C99 > > + || lang == DW_LANG_C11 || lang == DW_LANG_ObjC); > > + > > + > > +} > > + > > /* Return TRUE if the language is C++. */ > > > > static inline bool > > @@ -20952,8 +20966,16 @@ add_subscript_info (dw_die_ref type_die, tree > > type, bool collapse_p) > > > > if (!get_AT (subrange_die, DW_AT_lower_bound)) > > add_bound_info (subrange_die, DW_AT_lower_bound, lower, NULL); > > - if (upper && !get_AT (subrange_die, DW_AT_upper_bound)) > > - add_bound_info (subrange_die, DW_AT_upper_bound, upper, NULL); > > + if (!get_AT (subrange_die, DW_AT_upper_bound) > > + && !get_AT (subrange_die, DW_AT_count)) > > + { > > + if (upper) > > + add_bound_info (subrange_die, DW_AT_upper_bound, upper, NULL); > > + else if ((is_c () || is_cxx ()) && TYPE_SIZE (type))
Please use COMPLETE_TYPE_P (type) instead of TYPE_SIZE (type). I guess the restriction to C/C++ makes sense, at least for those we know the array element type can never be incomplete... Thus OK with the above change. Richard. > > + /* Zero-length array. */ > > + add_bound_info (subrange_die, DW_AT_count, > > + build_int_cst (TREE_TYPE (lower), 0), NULL); > > + } > > } > > > > /* Otherwise we have an array type with an unspecified length. The > > diff --git a/gcc/testsuite/gcc.dg/guality/zero-length-array.c > > b/gcc/testsuite/gcc.dg/guality/zero-length-array.c > > new file mode 100644 > > index 00000000000..33f34d98ac2 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/guality/zero-length-array.c > > @@ -0,0 +1,21 @@ > > +/* PR debug/86985 */ > > +/* { dg-do run } */ > > +/* { dg-options "-g" } */ > > + > > +struct { > > + int foo; > > + int bar[0]; > > +} zla; /* Zero length array. */ > > + > > +struct { > > + int foo; > > + int bar[]; > > +} fam; /* Flexible array member. */ > > + > > +int > > +main () > > +{ > > + /* { dg-final { gdb-test . "type:zla" "struct { int foo; int bar[0]; }" > > } } */ > > + /* { dg-final { gdb-test . "type:fam" "struct { int foo; int bar[]; }" } > > } */ > > + return 0; > > +} > > > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)