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

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