]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR fortran/97272 - Wrong answer from MAXLOC with character arg
authorHarald Anlauf <anlauf@gmx.de>
Sun, 4 Oct 2020 18:24:29 +0000 (20:24 +0200)
committerHarald Anlauf <anlauf@gmx.de>
Thu, 8 Oct 2020 16:41:02 +0000 (18:41 +0200)
The optional KIND argument to the MINLOC/MAXLOC intrinsic must not be
passed to the library function, as the kind conversion of the result
is treated explicitly elsewhere.

gcc/fortran/ChangeLog:

PR fortran/97272
* trans-intrinsic.c (strip_kind_from_actual): Helper function for
removal of KIND argument.
(gfc_conv_intrinsic_minmaxloc): Ignore KIND argument here, as it
is treated elsewhere.

gcc/testsuite/ChangeLog:

PR fortran/97272
* gfortran.dg/pr97272.f90: New test.

(cherry picked from commit 35d2c6b6e8a7448a84abbf967feeb78a29117014)

gcc/fortran/trans-intrinsic.c
gcc/testsuite/gfortran.dg/pr97272.f90 [new file with mode: 0644]

index fd8809902b7ae684ca931fcb19494fd734aa766a..29f8f932aa37e2b2ba971505db1a5ac88056635a 100644 (file)
@@ -5048,6 +5048,24 @@ gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
 }
 
 
+/* Remove unneeded kind= argument from actual argument list when the
+   result conversion is dealt with in a different place.  */
+
+static void
+strip_kind_from_actual (gfc_actual_arglist * actual)
+{
+  for (gfc_actual_arglist *a = actual; a; a = a->next)
+    {
+      gfc_actual_arglist *b = a->next;
+      if (b && b->name && strcmp (b->name, "kind") == 0)
+       {
+         a->next = b->next;
+         b->next = NULL;
+         gfc_free_actual_arglist (b);
+       }
+    }
+}
+
 /* Emit code for minloc or maxloc intrinsic.  There are many different cases
    we need to handle.  For performance reasons we sometimes create two
    loops instead of one, where the second one is much simpler.
@@ -5183,6 +5201,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
     {
       gfc_actual_arglist *a, *b;
       a = actual;
+      strip_kind_from_actual (a);
       while (a->next)
        {
          b = a->next;
diff --git a/gcc/testsuite/gfortran.dg/pr97272.f90 b/gcc/testsuite/gfortran.dg/pr97272.f90
new file mode 100644 (file)
index 0000000..e819038
--- /dev/null
@@ -0,0 +1,19 @@
+! { dg-do run }
+! PR fortran/97272 - Wrong answer from MAXLOC with character arg
+
+program test
+  implicit none
+  integer :: i, j, k, l = 10
+  character, allocatable :: a(:)
+  allocate (a(l))
+  a(:) = 'a'
+  l = l - 1
+  a(l) = 'b'
+  i = maxloc (a, dim=1)
+  j = maxloc (a, dim=1, kind=2)
+  k = maxloc (a, dim=1, kind=8, back=.true.)
+! print *, 'i = ', i, 'a(i) = ', a(i)
+! print *, 'j = ', j, 'a(j) = ', a(j)
+! print *, 'k = ', k, 'a(k) = ', a(k)
+  if (i /= l .or. j /= l .or. k /= l) stop 1
+end