Message ID | 20180817042900.GA19666@vader |
---|---|
State | New |
Headers | show |
Series | DWARF: add DW_AT_count to zero-length arrays | expand |
On Thu, Aug 16, 2018 at 9:29 PM Omar Sandoval <osandov@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? I don't think is really required. Zero-sized arrays are a GCC extension which was introduced before flexible array types were part of C. They should be interchangable in all places. Can you give an example of where they are not? A comment about the patch below. > > Thanks! > > 2018-08-16 Omar Sandoval <osandov@osandov.com> > > * dwarf2out.c (is_c_family): 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..b638942c156 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_family (void); > static bool is_cxx (void); > static bool is_cxx (const_tree); > static bool is_fortran (void); > @@ -5434,6 +5435,21 @@ 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 or C++. */ > + > +static inline bool > +is_c_family (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_C_plus_plus > + || lang == DW_LANG_ObjC_plus_plus || lang == DW_LANG_C_plus_plus_11 > + || lang == DW_LANG_C_plus_plus_14); > + > + > +} I think you should just "is_cxx () || is_c ()" and factor out the C/Objective-C parts (C++ is already done). This is will make it easier to maintain so if c++17 or c++20 comes along, only one place needs to be changed. Thanks, Andrew > + > /* Return TRUE if the language is C++. */ > > static inline bool > @@ -20918,12 +20934,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. */ > > 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_family () && 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
On Thu, Aug 16, 2018 at 10:27:48PM -0700, Andrew Pinski wrote: > On Thu, Aug 16, 2018 at 9:29 PM Omar Sandoval <osandov@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? > > I don't think is really required. Zero-sized arrays are a GCC > extension which was introduced before flexible array types were part > of C. They should be interchangable in all places. Can you give an > example of where they are not? See https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html. All of the following cases are only valid for zero-length arrays and not flexible arrays: sizeof(int [0]); struct foo { int bar[0]; }; struct foo { int bar[0]; int baz; }; union foo { int bar[0]; int baz; }; int arr[2][0]; The following is only valid for flexible arrays and not zero-length arrays: struct { int foo; int bar[]; } baz = {1, {2, 3}}; > A comment about the patch below. > > > > > Thanks! > > > > 2018-08-16 Omar Sandoval <osandov@osandov.com> > > > > * dwarf2out.c (is_c_family): 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..b638942c156 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_family (void); > > static bool is_cxx (void); > > static bool is_cxx (const_tree); > > static bool is_fortran (void); > > @@ -5434,6 +5435,21 @@ 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 or C++. */ > > + > > +static inline bool > > +is_c_family (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_C_plus_plus > > + || lang == DW_LANG_ObjC_plus_plus || lang == DW_LANG_C_plus_plus_11 > > + || lang == DW_LANG_C_plus_plus_14); > > + > > + > > +} > > I think you should just "is_cxx () || is_c ()" and factor out the > C/Objective-C parts (C++ is already done). > This is will make it easier to maintain so if c++17 or c++20 comes > along, only one place needs to be changed. Okay, will do. Thanks for taking a look! > > + > > /* Return TRUE if the language is C++. */ > > > > static inline bool > > @@ -20918,12 +20934,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. */ > > > > 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_family () && 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
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 <osandov@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 <osandov@osandov.com> * 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. */ 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
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 <osandov@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 <osandov@osandov.com> > > * 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. */ > > 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?
[ 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 <osandov@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 <osandov@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? Thanks, - Tom [debug] DWARF: add DW_AT_count to zero-length arrays 2018-09-04 Omar Sandoval <osandov@osandov.com> Tom de Vries <tdevries@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)) + /* 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; +}
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 <osandov@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 <osandov@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 <osandov@osandov.com> > Tom de Vries <tdevries@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)) > + /* 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; > +} >
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 <osandov@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 <osandov@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 <osandov@osandov.com> > > Tom de Vries <tdevries@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; > > +} > > > >
On 8/17/18 6:29 AM, Omar Sandoval wrote: > I don't have commit rights (first time contributor), so if this change is okay > could it please be applied? Hi, thanks for the patch, I've committed the approved version. [ In case you don't have one already ... ] if you want to continue contributing, it's a good idea to get a copyright assignment in place ( https://gcc.gnu.org/contribute.html#legal ). Thanks, - Tom
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 5a74131d332..b638942c156 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_family (void); static bool is_cxx (void); static bool is_cxx (const_tree); static bool is_fortran (void); @@ -5434,6 +5435,21 @@ 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 or C++. */ + +static inline bool +is_c_family (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_C_plus_plus + || lang == DW_LANG_ObjC_plus_plus || lang == DW_LANG_C_plus_plus_11 + || lang == DW_LANG_C_plus_plus_14); + + +} + /* Return TRUE if the language is C++. */ static inline bool @@ -20918,12 +20934,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. */ 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_family () && 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