|
|
132741 |
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
|
|
132741 |
From: Kevin Buettner <kevinb@redhat.com>
|
|
|
132741 |
Date: Mon, 24 May 2021 16:53:22 -0700
|
|
|
132741 |
Subject: gdb-rhbz1964167-fortran-clean-up-array-expression-evaluation.patch
|
|
|
132741 |
|
|
|
132741 |
;; [fortran] Backport Andrew Burgess's commit which cleans up
|
|
|
132741 |
;; array/string expression evaluation.
|
|
|
132741 |
|
|
|
132741 |
gdb/fortran: Clean up array/string expression evaluation
|
|
|
132741 |
|
|
|
132741 |
This commit is a refactor of part of the Fortran array and string
|
|
|
132741 |
handling code.
|
|
|
132741 |
|
|
|
132741 |
The current code is split into two blocks, linked, weirdly, with a
|
|
|
132741 |
goto. After this commit all the code is moved to its own function,
|
|
|
132741 |
and arrays and strings are now handled using the same code; this will
|
|
|
132741 |
be useful later when I want to add array stride support where strings
|
|
|
132741 |
will want to be treated just like arrays, but is a good clean up even
|
|
|
132741 |
without the array stride work, which is why I'm merging it now.
|
|
|
132741 |
|
|
|
132741 |
For now the new function is added as a static within eval.c, even
|
|
|
132741 |
though the function is Fortran only. A following commit will remove
|
|
|
132741 |
some of the Fortran specific code from eval.c into one of the Fortran
|
|
|
132741 |
specific files, including this new function.
|
|
|
132741 |
|
|
|
132741 |
There should be no user visible changes after this commit.
|
|
|
132741 |
|
|
|
132741 |
gdb/ChangeLog:
|
|
|
132741 |
|
|
|
132741 |
* eval.c (fortran_value_subarray): New function, content is taken
|
|
|
132741 |
from...
|
|
|
132741 |
(evaluate_subexp_standard): ...here, in two places. Now arrays
|
|
|
132741 |
and strings both call the new function.
|
|
|
132741 |
(calc_f77_array_dims): Add header comment, handle strings.
|
|
|
132741 |
|
|
|
132741 |
diff --git a/gdb/eval.c b/gdb/eval.c
|
|
|
132741 |
--- a/gdb/eval.c
|
|
|
132741 |
+++ b/gdb/eval.c
|
|
|
132741 |
@@ -1260,6 +1260,67 @@ is_integral_or_integral_reference (struct type *type)
|
|
|
132741 |
&& is_integral_type (TYPE_TARGET_TYPE (type)));
|
|
|
132741 |
}
|
|
|
132741 |
|
|
|
132741 |
+/* Called from evaluate_subexp_standard to perform array indexing, and
|
|
|
132741 |
+ sub-range extraction, for Fortran. As well as arrays this function
|
|
|
132741 |
+ also handles strings as they can be treated like arrays of characters.
|
|
|
132741 |
+ ARRAY is the array or string being accessed. EXP, POS, and NOSIDE are
|
|
|
132741 |
+ as for evaluate_subexp_standard, and NARGS is the number of arguments
|
|
|
132741 |
+ in this access (e.g. 'array (1,2,3)' would be NARGS 3). */
|
|
|
132741 |
+
|
|
|
132741 |
+static struct value *
|
|
|
132741 |
+fortran_value_subarray (struct value *array, struct expression *exp,
|
|
|
132741 |
+ int *pos, int nargs, enum noside noside)
|
|
|
132741 |
+{
|
|
|
132741 |
+ if (exp->elts[*pos].opcode == OP_RANGE)
|
|
|
132741 |
+ return value_f90_subarray (array, exp, pos, noside);
|
|
|
132741 |
+
|
|
|
132741 |
+ if (noside == EVAL_SKIP)
|
|
|
132741 |
+ {
|
|
|
132741 |
+ skip_undetermined_arglist (nargs, exp, pos, noside);
|
|
|
132741 |
+ /* Return the dummy value with the correct type. */
|
|
|
132741 |
+ return array;
|
|
|
132741 |
+ }
|
|
|
132741 |
+
|
|
|
132741 |
+ LONGEST subscript_array[MAX_FORTRAN_DIMS];
|
|
|
132741 |
+ int ndimensions = 1;
|
|
|
132741 |
+ struct type *type = check_typedef (value_type (array));
|
|
|
132741 |
+
|
|
|
132741 |
+ if (nargs > MAX_FORTRAN_DIMS)
|
|
|
132741 |
+ error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS);
|
|
|
132741 |
+
|
|
|
132741 |
+ ndimensions = calc_f77_array_dims (type);
|
|
|
132741 |
+
|
|
|
132741 |
+ if (nargs != ndimensions)
|
|
|
132741 |
+ error (_("Wrong number of subscripts"));
|
|
|
132741 |
+
|
|
|
132741 |
+ gdb_assert (nargs > 0);
|
|
|
132741 |
+
|
|
|
132741 |
+ /* Now that we know we have a legal array subscript expression let us
|
|
|
132741 |
+ actually find out where this element exists in the array. */
|
|
|
132741 |
+
|
|
|
132741 |
+ /* Take array indices left to right. */
|
|
|
132741 |
+ for (int i = 0; i < nargs; i++)
|
|
|
132741 |
+ {
|
|
|
132741 |
+ /* Evaluate each subscript; it must be a legal integer in F77. */
|
|
|
132741 |
+ value *arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
|
|
|
132741 |
+
|
|
|
132741 |
+ /* Fill in the subscript array. */
|
|
|
132741 |
+ subscript_array[i] = value_as_long (arg2);
|
|
|
132741 |
+ }
|
|
|
132741 |
+
|
|
|
132741 |
+ /* Internal type of array is arranged right to left. */
|
|
|
132741 |
+ for (int i = nargs; i > 0; i--)
|
|
|
132741 |
+ {
|
|
|
132741 |
+ struct type *array_type = check_typedef (value_type (array));
|
|
|
132741 |
+ LONGEST index = subscript_array[i - 1];
|
|
|
132741 |
+
|
|
|
132741 |
+ array = value_subscripted_rvalue (array, index,
|
|
|
132741 |
+ f77_get_lowerbound (array_type));
|
|
|
132741 |
+ }
|
|
|
132741 |
+
|
|
|
132741 |
+ return array;
|
|
|
132741 |
+}
|
|
|
132741 |
+
|
|
|
132741 |
struct value *
|
|
|
132741 |
evaluate_subexp_standard (struct type *expect_type,
|
|
|
132741 |
struct expression *exp, int *pos,
|
|
|
132741 |
@@ -1953,33 +2014,8 @@ evaluate_subexp_standard (struct type *expect_type,
|
|
|
132741 |
switch (code)
|
|
|
132741 |
{
|
|
|
132741 |
case TYPE_CODE_ARRAY:
|
|
|
132741 |
- if (exp->elts[*pos].opcode == OP_RANGE)
|
|
|
132741 |
- return value_f90_subarray (arg1, exp, pos, noside);
|
|
|
132741 |
- else
|
|
|
132741 |
- {
|
|
|
132741 |
- if (noside == EVAL_SKIP)
|
|
|
132741 |
- {
|
|
|
132741 |
- skip_undetermined_arglist (nargs, exp, pos, noside);
|
|
|
132741 |
- /* Return the dummy value with the correct type. */
|
|
|
132741 |
- return arg1;
|
|
|
132741 |
- }
|
|
|
132741 |
- goto multi_f77_subscript;
|
|
|
132741 |
- }
|
|
|
132741 |
-
|
|
|
132741 |
case TYPE_CODE_STRING:
|
|
|
132741 |
- if (exp->elts[*pos].opcode == OP_RANGE)
|
|
|
132741 |
- return value_f90_subarray (arg1, exp, pos, noside);
|
|
|
132741 |
- else
|
|
|
132741 |
- {
|
|
|
132741 |
- if (noside == EVAL_SKIP)
|
|
|
132741 |
- {
|
|
|
132741 |
- skip_undetermined_arglist (nargs, exp, pos, noside);
|
|
|
132741 |
- /* Return the dummy value with the correct type. */
|
|
|
132741 |
- return arg1;
|
|
|
132741 |
- }
|
|
|
132741 |
- arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
|
|
|
132741 |
- return value_subscript (arg1, value_as_long (arg2));
|
|
|
132741 |
- }
|
|
|
132741 |
+ return fortran_value_subarray (arg1, exp, pos, nargs, noside);
|
|
|
132741 |
|
|
|
132741 |
case TYPE_CODE_PTR:
|
|
|
132741 |
case TYPE_CODE_FUNC:
|
|
|
132741 |
@@ -2400,49 +2436,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
|
|
132741 |
}
|
|
|
132741 |
return (arg1);
|
|
|
132741 |
|
|
|
132741 |
- multi_f77_subscript:
|
|
|
132741 |
- {
|
|
|
132741 |
- LONGEST subscript_array[MAX_FORTRAN_DIMS];
|
|
|
132741 |
- int ndimensions = 1, i;
|
|
|
132741 |
- struct value *array = arg1;
|
|
|
132741 |
-
|
|
|
132741 |
- if (nargs > MAX_FORTRAN_DIMS)
|
|
|
132741 |
- error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS);
|
|
|
132741 |
-
|
|
|
132741 |
- ndimensions = calc_f77_array_dims (type);
|
|
|
132741 |
-
|
|
|
132741 |
- if (nargs != ndimensions)
|
|
|
132741 |
- error (_("Wrong number of subscripts"));
|
|
|
132741 |
-
|
|
|
132741 |
- gdb_assert (nargs > 0);
|
|
|
132741 |
-
|
|
|
132741 |
- /* Now that we know we have a legal array subscript expression
|
|
|
132741 |
- let us actually find out where this element exists in the array. */
|
|
|
132741 |
-
|
|
|
132741 |
- /* Take array indices left to right. */
|
|
|
132741 |
- for (i = 0; i < nargs; i++)
|
|
|
132741 |
- {
|
|
|
132741 |
- /* Evaluate each subscript; it must be a legal integer in F77. */
|
|
|
132741 |
- arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
|
|
|
132741 |
-
|
|
|
132741 |
- /* Fill in the subscript array. */
|
|
|
132741 |
-
|
|
|
132741 |
- subscript_array[i] = value_as_long (arg2);
|
|
|
132741 |
- }
|
|
|
132741 |
-
|
|
|
132741 |
- /* Internal type of array is arranged right to left. */
|
|
|
132741 |
- for (i = nargs; i > 0; i--)
|
|
|
132741 |
- {
|
|
|
132741 |
- struct type *array_type = check_typedef (value_type (array));
|
|
|
132741 |
- LONGEST index = subscript_array[i - 1];
|
|
|
132741 |
-
|
|
|
132741 |
- array = value_subscripted_rvalue (array, index,
|
|
|
132741 |
- f77_get_lowerbound (array_type));
|
|
|
132741 |
- }
|
|
|
132741 |
-
|
|
|
132741 |
- return array;
|
|
|
132741 |
- }
|
|
|
132741 |
-
|
|
|
132741 |
case BINOP_LOGICAL_AND:
|
|
|
132741 |
arg1 = evaluate_subexp (nullptr, exp, pos, noside);
|
|
|
132741 |
if (noside == EVAL_SKIP)
|
|
|
132741 |
@@ -3354,12 +3347,17 @@ parse_and_eval_type (char *p, int length)
|
|
|
132741 |
return expr->elts[1].type;
|
|
|
132741 |
}
|
|
|
132741 |
|
|
|
132741 |
+/* Return the number of dimensions for a Fortran array or string. */
|
|
|
132741 |
+
|
|
|
132741 |
int
|
|
|
132741 |
calc_f77_array_dims (struct type *array_type)
|
|
|
132741 |
{
|
|
|
132741 |
int ndimen = 1;
|
|
|
132741 |
struct type *tmp_type;
|
|
|
132741 |
|
|
|
132741 |
+ if ((array_type->code () == TYPE_CODE_STRING))
|
|
|
132741 |
+ return 1;
|
|
|
132741 |
+
|
|
|
132741 |
if ((array_type->code () != TYPE_CODE_ARRAY))
|
|
|
132741 |
error (_("Can't get dimensions for a non-array type"));
|
|
|
132741 |
|