diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d9d0f85135f..67de5ca80bb 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2021-04-22 Simon Marchi + + PR gdb/27757 + * python/py-type.c (typy_range): Check that bounds are constant + before accessing them as such. + * guile/scm-type.c (gdbscm_type_range): Likewise. + 2021-04-22 Tankut Baris Aktemur * Makefile.in (COMMON_SFILES): Remove continuations.c. diff --git a/gdb/guile/scm-type.c b/gdb/guile/scm-type.c index dd45d8e8b35..11693844edc 100644 --- a/gdb/guile/scm-type.c +++ b/gdb/guile/scm-type.c @@ -823,8 +823,15 @@ gdbscm_type_range (SCM self) case TYPE_CODE_ARRAY: case TYPE_CODE_STRING: case TYPE_CODE_RANGE: - low = type->bounds ()->low.const_val (); - high = type->bounds ()->high.const_val (); + if (type->bounds ()->low.kind () == PROP_CONST) + low = type->bounds ()->low.const_val (); + else + low = 0; + + if (type->bounds ()->high.kind () == PROP_CONST) + high = type->bounds ()->high.const_val (); + else + high = 0; break; } diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index bf707078841..148e4a6aa3a 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -592,8 +592,15 @@ typy_range (PyObject *self, PyObject *args) case TYPE_CODE_ARRAY: case TYPE_CODE_STRING: case TYPE_CODE_RANGE: - low = type->bounds ()->low.const_val (); - high = type->bounds ()->high.const_val ();; + if (type->bounds ()->low.kind () == PROP_CONST) + low = type->bounds ()->low.const_val (); + else + low = 0; + + if (type->bounds ()->high.kind () == PROP_CONST) + high = type->bounds ()->high.const_val (); + else + high = 0; break; } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 3099cbacac3..9730658299b 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2021-04-22 Simon Marchi + + PR gdb/27757 + * gdb.python/flexible-array-member.c: New test. + * gdb.python/flexible-array-member.exp: New test. + * gdb.guile/scm-type.exp (test_range): Add test for flexible + array member. + * gdb.guile/scm-type.c (struct flex_member): New. + (main): Use it. + 2021-04-22 Tom Tromey * gdb.rust/modules.exp: Add checks for syntax errors. diff --git a/gdb/testsuite/gdb.guile/scm-type.c b/gdb/testsuite/gdb.guile/scm-type.c index 782b8fe70cf..64f5f02efed 100644 --- a/gdb/testsuite/gdb.guile/scm-type.c +++ b/gdb/testsuite/gdb.guile/scm-type.c @@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include + struct s { int a; @@ -53,6 +55,12 @@ enum E struct s vec_data_1 = {1, 1}; struct s vec_data_2 = {1, 2}; +struct flex_member +{ + int n; + int items[]; +}; + int main () { @@ -72,6 +80,10 @@ main () st.b = 5; e = v2; + + struct flex_member *f = (struct flex_member *) malloc (100); + f->items[0] = 111; + f->items[1] = 222; return 0; /* break to inspect struct and array. */ } diff --git a/gdb/testsuite/gdb.guile/scm-type.exp b/gdb/testsuite/gdb.guile/scm-type.exp index 8778cdb36cb..517c99f8369 100644 --- a/gdb/testsuite/gdb.guile/scm-type.exp +++ b/gdb/testsuite/gdb.guile/scm-type.exp @@ -261,6 +261,18 @@ proc test_range {} { "ERROR: .*: Wrong type argument in position 1 \\(expecting ranged type\\): .*" \ "check range for non ranged type" } + + with_test_prefix "on flexible array member" { + gdb_scm_test_silent_cmd "print f" "print value (f)" + gdb_scm_test_silent_cmd "guile (define f (history-ref 0))" \ + "get value (f) from history" + gdb_test "guile (print (type-range (field-type (type-field (value-type (value-dereference f)) \"items\"))))" \ + "= \\(0 0\\)" + gdb_test "guile (print (value-subscript (value-field (value-dereference f) \"items\") 0))" \ + "= 111" + gdb_test "guile (print (value-subscript (value-field (value-dereference f) \"items\") 1))" \ + "= 222" + } } } diff --git a/gdb/testsuite/gdb.python/flexible-array-member.c b/gdb/testsuite/gdb.python/flexible-array-member.c new file mode 100644 index 00000000000..79815e2d38e --- /dev/null +++ b/gdb/testsuite/gdb.python/flexible-array-member.c @@ -0,0 +1,70 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2020-2021 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +struct no_size +{ + int n; + int items[]; +}; + +struct zero_size +{ + int n; + int items[0]; +}; + +struct zero_size_only +{ + int items[0]; +}; + +struct no_size *ns; +struct zero_size *zs; +struct zero_size_only *zso; + +static void +break_here (void) +{ +} + +int +main (void) +{ + ns = (struct no_size *) malloc (sizeof (*ns) + 3 * sizeof (int)); + zs = (struct zero_size *) malloc (sizeof (*zs) + 3 * sizeof (int)); + zso = (struct zero_size_only *) malloc (sizeof (*zso) + 3 * sizeof (int)); + + ns->n = 3; + ns->items[0] = 101; + ns->items[1] = 102; + ns->items[2] = 103; + + zs->n = 3; + zs->items[0] = 201; + zs->items[1] = 202; + zs->items[2] = 203; + + zso->items[0] = 301; + zso->items[1] = 302; + zso->items[2] = 303; + + break_here (); + + return 0; +} diff --git a/gdb/testsuite/gdb.python/flexible-array-member.exp b/gdb/testsuite/gdb.python/flexible-array-member.exp new file mode 100644 index 00000000000..3739c9a9e5c --- /dev/null +++ b/gdb/testsuite/gdb.python/flexible-array-member.exp @@ -0,0 +1,81 @@ +# Copyright 2020-2021 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Test getting the range of flexible array members in Python. + +standard_testfile + +if { [prepare_for_testing "failed to prepare" \ + ${testfile} ${srcfile}] } { + return +} + +if { ![runto break_here] } { + untested "could not run to break_here" + return +} + +# The various cases are: +# +# - ns: flexible array member with no size +# - zs: flexible array member with size 0 (GNU C extension that predates the +# standardization of the feature, but widely supported) +# - zso: zero-size only, a corner case where the array is the sole member of +# the structure + +gdb_test "python ns = gdb.parse_and_eval('ns').dereference()" +gdb_test "python zs = gdb.parse_and_eval('zs').dereference()" +gdb_test "python zso = gdb.parse_and_eval('zso').dereference()" + +# Print the whole structure. + +gdb_test "python print(ns)" "{n = 3, items = $hex}" +gdb_test "python print(zs)" "{n = 3, items = $hex}" +gdb_test "python print(zso)" "{items = $hex}" + +# Print all items. + +gdb_test "python print(ns\['items'\])" "$hex" +gdb_test "python print(ns\['items'\]\[0\])" "101" +gdb_test "python print(ns\['items'\]\[1\])" "102" +gdb_test "python print(ns\['items'\]\[2\])" "103" + +gdb_test "python print(zs\['items'\])" "$hex" +gdb_test "python print(zs\['items'\]\[0\])" "201" +gdb_test "python print(zs\['items'\]\[1\])" "202" +gdb_test "python print(zs\['items'\]\[2\])" "203" + +gdb_test "python print(zso\['items'\])" "$hex" +gdb_test "python print(zso\['items'\]\[0\])" "301" +gdb_test "python print(zso\['items'\]\[1\])" "302" +gdb_test "python print(zso\['items'\]\[2\])" "303" + +# Check taking the address of array elements (how PR 28675 was originally +# reported). + +gdb_test "python print(ns\['items'\] == ns\['items'\]\[0\].address)" "True" +gdb_test "python print(ns\['items'\]\[0\].address + 1 == ns\['items'\]\[1\].address)" "True" +gdb_test "python print(zs\['items'\] == zs\['items'\]\[0\].address)" "True" +gdb_test "python print(zs\['items'\]\[0\].address + 1 == zs\['items'\]\[1\].address)" "True" +gdb_test "python print(zso\['items'\] == zso\['items'\]\[0\].address)" "True" +gdb_test "python print(zso\['items'\]\[0\].address + 1 == zso\['items'\]\[1\].address)" "True" + +# Verify the range attribute. It looks a bit inconsistent that the high bound +# is sometimes 0, sometimes -1, but that's what GDB produces today, so that's +# what we test. + +gdb_test "python print(ns\['items'\].type.range())" "\\(0, 0\\)" +gdb_test "python print(zs\['items'\].type.range())" "\\(0, -1\\)" +gdb_test "python print(zso\['items'\].type.range())" "\\(0, -1\\)"