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