Blame SOURCES/gdb-rhbz1964167-fortran-array-strides-in-expressions.patch

0a406a
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
0a406a
From: Kevin Buettner <kevinb@redhat.com>
0a406a
Date: Mon, 24 May 2021 22:30:32 -0700
0a406a
Subject: gdb-rhbz1964167-fortran-array-strides-in-expressions.patch
0a406a
0a406a
;; [fortran] Backport Andrew Burgess's commit which adds support
0a406a
;; for array strides in expressions.
0a406a
0a406a
gdb/fortran: add support for parsing array strides in expressions
0a406a
0a406a
With this commit GDB now understands the syntax of Fortran array
0a406a
strides, a user can type an expression including an array stride, but
0a406a
they will only get an error informing them that array strides are not
0a406a
supported.
0a406a
0a406a
This alone is an improvement on what we had before in GDB, better to
0a406a
give the user a helpful message that a particular feature is not
0a406a
supported than to just claim a syntax error.
0a406a
0a406a
Before:
0a406a
0a406a
  (gdb) p array (1:10:2, 2:10:2)
0a406a
  A syntax error in expression, near `:2, 2:10:2)'.
0a406a
0a406a
Now:
0a406a
0a406a
  (gdb) p array (1:10:2, 2:10:2)
0a406a
  Fortran array strides are not currently supported
0a406a
0a406a
Later commits will allow GDB to handle array strides correctly.
0a406a
0a406a
gdb/ChangeLog:
0a406a
0a406a
	* expprint.c (dump_subexp_body_standard): Print RANGE_HAS_STRIDE.
0a406a
	* expression.h (enum range_type): Add RANGE_HAS_STRIDE.
0a406a
	* f-exp.y (arglist): Allow for a series of subranges.
0a406a
	(subrange): Add cases for subranges with strides.
0a406a
	* f-lang.c (value_f90_subarray): Catch use of array strides and
0a406a
	throw an error.
0a406a
	* parse.c (operator_length_standard): Handle RANGE_HAS_STRIDE.
0a406a
0a406a
gdb/testsuite/ChangeLog:
0a406a
0a406a
	* gdb.fortran/array-slices.exp: Add a new test.
0a406a
0a406a
diff --git a/gdb/expprint.c b/gdb/expprint.c
0a406a
--- a/gdb/expprint.c
0a406a
+++ b/gdb/expprint.c
0a406a
@@ -1118,12 +1118,16 @@ dump_subexp_body_standard (struct expression *exp,
0a406a
 	fputs_filtered ("..", stream);
0a406a
 	if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
0a406a
 	  fputs_filtered ("EXP", stream);
0a406a
+	if (range_flag & RANGE_HAS_STRIDE)
0a406a
+	  fputs_filtered (":EXP", stream);
0a406a
 	fputs_filtered ("'", stream);
0a406a
 
0a406a
 	if (!(range_flag & RANGE_LOW_BOUND_DEFAULT))
0a406a
 	  elt = dump_subexp (exp, stream, elt);
0a406a
 	if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
0a406a
 	  elt = dump_subexp (exp, stream, elt);
0a406a
+	if (range_flag & RANGE_HAS_STRIDE)
0a406a
+	  elt = dump_subexp (exp, stream, elt);
0a406a
       }
0a406a
       break;
0a406a
 
0a406a
diff --git a/gdb/expression.h b/gdb/expression.h
0a406a
--- a/gdb/expression.h
0a406a
+++ b/gdb/expression.h
0a406a
@@ -199,6 +199,9 @@ enum range_flag : unsigned
0a406a
 
0a406a
   /* The high bound of this range is exclusive.  */
0a406a
   RANGE_HIGH_BOUND_EXCLUSIVE = 1 << 2,
0a406a
+
0a406a
+  /* The range has a stride.  */
0a406a
+  RANGE_HAS_STRIDE = 1 << 3,
0a406a
 };
0a406a
 
0a406a
 DEF_ENUM_FLAGS_TYPE (enum range_flag, range_flags);
0a406a
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
0a406a
--- a/gdb/f-exp.y
0a406a
+++ b/gdb/f-exp.y
0a406a
@@ -284,6 +284,10 @@ arglist	:	arglist ',' exp   %prec ABOVE_COMMA
0a406a
 			{ pstate->arglist_len++; }
0a406a
 	;
0a406a
 
0a406a
+arglist	:	arglist ',' subrange   %prec ABOVE_COMMA
0a406a
+			{ pstate->arglist_len++; }
0a406a
+	;
0a406a
+
0a406a
 /* There are four sorts of subrange types in F90.  */
0a406a
 
0a406a
 subrange:	exp ':' exp	%prec ABOVE_COMMA
0a406a
@@ -314,6 +318,38 @@ subrange:	':'	%prec ABOVE_COMMA
0a406a
 			  write_exp_elt_opcode (pstate, OP_RANGE); }
0a406a
 	;
0a406a
 
0a406a
+/* And each of the four subrange types can also have a stride.  */
0a406a
+subrange:	exp ':' exp ':' exp	%prec ABOVE_COMMA
0a406a
+			{ write_exp_elt_opcode (pstate, OP_RANGE);
0a406a
+			  write_exp_elt_longcst (pstate, RANGE_HAS_STRIDE);
0a406a
+			  write_exp_elt_opcode (pstate, OP_RANGE); }
0a406a
+	;
0a406a
+
0a406a
+subrange:	exp ':' ':' exp	%prec ABOVE_COMMA
0a406a
+			{ write_exp_elt_opcode (pstate, OP_RANGE);
0a406a
+			  write_exp_elt_longcst (pstate,
0a406a
+						 (RANGE_HIGH_BOUND_DEFAULT
0a406a
+						  | RANGE_HAS_STRIDE));
0a406a
+			  write_exp_elt_opcode (pstate, OP_RANGE); }
0a406a
+	;
0a406a
+
0a406a
+subrange:	':' exp ':' exp	%prec ABOVE_COMMA
0a406a
+			{ write_exp_elt_opcode (pstate, OP_RANGE);
0a406a
+			  write_exp_elt_longcst (pstate,
0a406a
+						 (RANGE_LOW_BOUND_DEFAULT
0a406a
+						  | RANGE_HAS_STRIDE));
0a406a
+			  write_exp_elt_opcode (pstate, OP_RANGE); }
0a406a
+	;
0a406a
+
0a406a
+subrange:	':' ':' exp	%prec ABOVE_COMMA
0a406a
+			{ write_exp_elt_opcode (pstate, OP_RANGE);
0a406a
+			  write_exp_elt_longcst (pstate,
0a406a
+						 (RANGE_LOW_BOUND_DEFAULT
0a406a
+						  | RANGE_HIGH_BOUND_DEFAULT
0a406a
+						  | RANGE_HAS_STRIDE));
0a406a
+			  write_exp_elt_opcode (pstate, OP_RANGE); }
0a406a
+	;
0a406a
+
0a406a
 complexnum:     exp ',' exp 
0a406a
                 	{ }                          
0a406a
         ;
0a406a
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
0a406a
--- a/gdb/f-lang.c
0a406a
+++ b/gdb/f-lang.c
0a406a
@@ -124,7 +124,7 @@ value_f90_subarray (struct value *array,
0a406a
 		    struct expression *exp, int *pos, enum noside noside)
0a406a
 {
0a406a
   int pc = (*pos) + 1;
0a406a
-  LONGEST low_bound, high_bound;
0a406a
+  LONGEST low_bound, high_bound, stride;
0a406a
   struct type *range = check_typedef (value_type (array)->index_type ());
0a406a
   enum range_flag range_flag
0a406a
     = (enum range_flag) longest_to_int (exp->elts[pc].longconst);
0a406a
@@ -141,6 +141,14 @@ value_f90_subarray (struct value *array,
0a406a
   else
0a406a
     high_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
0a406a
 
0a406a
+  if (range_flag & RANGE_HAS_STRIDE)
0a406a
+    stride = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
0a406a
+  else
0a406a
+    stride = 1;
0a406a
+
0a406a
+  if (stride != 1)
0a406a
+    error (_("Fortran array strides are not currently supported"));
0a406a
+
0a406a
   return value_slice (array, low_bound, high_bound - low_bound + 1);
0a406a
 }
0a406a
 
0a406a
diff --git a/gdb/parse.c b/gdb/parse.c
0a406a
--- a/gdb/parse.c
0a406a
+++ b/gdb/parse.c
0a406a
@@ -924,6 +924,8 @@ operator_length_standard (const struct expression *expr, int endpos,
0a406a
       /* Assume the range has 2 arguments (low bound and high bound), then
0a406a
 	 reduce the argument count if any bounds are set to default.  */
0a406a
       args = 2;
0a406a
+      if (range_flag & RANGE_HAS_STRIDE)
0a406a
+	++args;
0a406a
       if (range_flag & RANGE_LOW_BOUND_DEFAULT)
0a406a
 	--args;
0a406a
       if (range_flag & RANGE_HIGH_BOUND_DEFAULT)
0a406a
diff --git a/gdb/testsuite/gdb.fortran/array-slices.exp b/gdb/testsuite/gdb.fortran/array-slices.exp
0a406a
--- a/gdb/testsuite/gdb.fortran/array-slices.exp
0a406a
+++ b/gdb/testsuite/gdb.fortran/array-slices.exp
0a406a
@@ -66,3 +66,19 @@ foreach result $array_contents msg $message_strings {
0a406a
 }
0a406a
 
0a406a
 gdb_continue_to_breakpoint "continue to Final Breakpoint"
0a406a
+
0a406a
+# Next test that asking for an array with stride at the CLI gives an
0a406a
+# error.
0a406a
+clean_restart ${testfile}
0a406a
+
0a406a
+if ![fortran_runto_main] then {
0a406a
+    perror "couldn't run to main"
0a406a
+    continue
0a406a
+}
0a406a
+
0a406a
+gdb_breakpoint "show"
0a406a
+gdb_continue_to_breakpoint "show"
0a406a
+gdb_test "up" ".*"
0a406a
+gdb_test "p array (1:10:2, 1:10:2)" \
0a406a
+    "Fortran array strides are not currently supported" \
0a406a
+    "using array stride gives an error"