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

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