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

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