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

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