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

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