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

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