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

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