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

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