Add gdb.fortran/vla-stride.exp and report a bug (was: Re: [review] gdb/fortran: array stride support)

Message ID 87sgkivgx2.fsf_-_@redhat.com
State New, archived
Headers

Commit Message

Sergio Durigan Junior Jan. 14, 2020, 3:46 a.m. UTC
  On Thursday, November 14 2019, Andrew Burgess wrote:

> Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/627
> ......................................................................
>
> gdb/fortran: array stride support
> [...]

Hey Andrew,

I found a problem with this patch, and I'd like to know if you've
noticed this as well.  I first encountered the problem while doing
downstream work on Fedora GDB for Fedora Rawhide; as you are probably
aware, we carry *a lot* of local Fortran VLA patches on Fedora GDB (if
you're not aware about this, feel free to get in touch with me and I'll
be more than happy to explain the situation to you).  However, I am able
to reproduce the problem on upstream GDB as well.

On Fedora GDB, we carry a testcase called gdb.fortran/vla-stride.exp.  I'm
attaching it to this message.  One of its tests fails with:

  (gdb) print pvla
  Cannot access memory at address 0x426000
  FAIL: gdb.fortran/vla-stride.exp: print single-element

See more below.

> diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
> index fd1c765..968aeb2 100644
> --- a/gdb/gdbtypes.c
> +++ b/gdb/gdbtypes.c
[...]
>  /* Create a range type using either a blank type supplied in
>     RESULT_TYPE, or creating a new type, inheriting the objfile from
>     INDEX_TYPE.
> @@ -982,7 +1011,8 @@
>  has_static_range (const struct range_bounds *bounds)
>  {
>    return (bounds->low.kind == PROP_CONST
> -	  && bounds->high.kind == PROP_CONST);
> +	  && bounds->high.kind == PROP_CONST
> +	  && bounds->stride.kind == PROP_CONST);
>  }
>  
>  
> @@ -1189,6 +1219,15 @@
>  	  && !type_not_allocated (result_type)))
>      {
>        LONGEST low_bound, high_bound;
> +      unsigned int stride;
> +
> +      /* If the array itself doesn't provide a stride value then take
> +	 whatever stride the range provides.  Don't update BIT_STRIDE as
> +	 we don't want to place the stride value from the range into this
> +	 arrays bit size field.  */
> +      stride = bit_stride;
> +      if (stride == 0)
> +	stride = TYPE_BIT_STRIDE (range_type);
>  
>        if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
>  	low_bound = high_bound = 0;
> @@ -1198,9 +1237,9 @@
>  	 In such cases, the array length should be zero.  */
>        if (high_bound < low_bound)
>  	TYPE_LENGTH (result_type) = 0;
> -      else if (bit_stride > 0)
> +      else if (stride > 0)
>  	TYPE_LENGTH (result_type) =
> -	  (bit_stride * (high_bound - low_bound + 1) + 7) / 8;
> +	  (stride * (high_bound - low_bound + 1) + 7) / 8;

After spending a lot of time investigating this, I found that the
problem because TYPE_LENGTH (result_type) will be set to a ridiculously
high value here, due to the fact that stride (and therefore bit_stride)
will also be ridiculously high.  bit_stride is obtained back in
gdbtypes.c:resolve_dynamic_array_or_string as:

  ...
  else
    bit_stride = TYPE_FIELD_BITSIZE (type, 0);

TBH, I haven't investigated further because this was taking too long,
and I decided to call on the experts.  The code above was added by Joel,
so I took the liberty to Cc him as well.

The test can be found below.

Thanks,
  

Patch

From a2192e20726e05463405297d16d0661841360f6a Mon Sep 17 00:00:00 2001
From: Sergio Durigan Junior <sergiodj@redhat.com>
Date: Mon, 13 Jan 2020 22:43:37 -0500
Subject: [PATCH] Add gdb.fortran/vla-stride.exp

This patch adds a new testcase, gdb.fortran/vla-stride.exp, in order
to extend the Fortran stride tests.

This test was part of Fedora GDB.

gdb/testsuite/ChangeLog:
2020-01-14  Sergio Durigan Junior  <sergiodj@redhat.com>

	* gdb.fortran/vla-stride.exp: New file.
	* gdb.fortran/vla-stride.f90: New file.

Change-Id: Ia9756868b550e75143d805f1ed2763a43017804d
---
 gdb/testsuite/gdb.fortran/vla-stride.exp | 44 ++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/vla-stride.f90 | 29 ++++++++++++++++
 2 files changed, 73 insertions(+)
 create mode 100644 gdb/testsuite/gdb.fortran/vla-stride.exp
 create mode 100644 gdb/testsuite/gdb.fortran/vla-stride.f90

diff --git a/gdb/testsuite/gdb.fortran/vla-stride.exp b/gdb/testsuite/gdb.fortran/vla-stride.exp
new file mode 100644
index 0000000000..15573e22cb
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/vla-stride.exp
@@ -0,0 +1,44 @@ 
+# Copyright 2016-2020 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 <http://www.gnu.org/licenses/>.
+
+standard_testfile ".f90"
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
+    {debug f90 quiet}] } {
+    return -1
+}
+
+if ![runto MAIN__] then {
+    perror "couldn't run to breakpoint MAIN__"
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "re-reverse-elements"]
+gdb_continue_to_breakpoint "re-reverse-elements"
+gdb_test "print pvla" " = \\\(1, 2, 3, 4, 5, 6, 7, 8, 9, 10\\\)" \
+  "print re-reverse-elements"
+gdb_test "print pvla(1)" " = 1" "print first re-reverse-element"
+gdb_test "print pvla(10)" " = 10" "print last re-reverse-element"
+
+gdb_breakpoint [gdb_get_line_number "odd-elements"]
+gdb_continue_to_breakpoint "odd-elements"
+gdb_test "print pvla" " = \\\(1, 3, 5, 7, 9\\\)" "print odd-elements"
+gdb_test "print pvla(1)" " = 1" "print first odd-element"
+gdb_test "print pvla(5)" " = 9" "print last odd-element"
+
+gdb_breakpoint [gdb_get_line_number "single-element"]
+gdb_continue_to_breakpoint "single-element"
+gdb_test "print pvla" " = \\\(5\\\)" "print single-element"
+gdb_test "print pvla(1)" " = 5" "print one single-element"
diff --git a/gdb/testsuite/gdb.fortran/vla-stride.f90 b/gdb/testsuite/gdb.fortran/vla-stride.f90
new file mode 100644
index 0000000000..22b8a65278
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/vla-stride.f90
@@ -0,0 +1,29 @@ 
+! Copyright 2016-2020 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 <http://www.gnu.org/licenses/>.
+
+program vla_stride
+  integer, target, allocatable :: vla (:)
+  integer, pointer :: pvla (:)
+
+  allocate(vla(10))
+  vla = (/ (I, I = 1,10) /)
+
+  pvla => vla(10:1:-1)
+  pvla => pvla(10:1:-1)
+  pvla => vla(1:10:2)   ! re-reverse-elements
+  pvla => vla(5:4:-2)   ! odd-elements
+
+  pvla => null()        ! single-element
+end program vla_stride
-- 
2.21.0