Blame SOURCES/gdb-rhbz1964167-fortran-clean-up-array-expression-evaluation.patch

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