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

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