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

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