https://gcc.gnu.org/g:40122a405386a8b67c11bbaad523ffce5c1c7855

commit 40122a405386a8b67c11bbaad523ffce5c1c7855
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Fri Aug 2 14:24:34 2024 +0200

    fortran: Support optional dummy as BACK argument of MINLOC/MAXLOC.
    
    Protect the evaluation of BACK with a check that the reference is non-null
    in case the expression is an optional dummy, in the inline code generated
    for MINLOC and MAXLOC.
    
    This change contains a revert of the non-testsuite part of commit
    r15-1994-ga55d24b3cf7f4d07492bb8e6fcee557175b47ea3, which factored the
    evaluation of BACK out of the loop using the scalarizer.  It was a bad idea,
    because delegating the argument evaluation to the scalarizer makes it
    cumbersome to add a null pointer check next to the evaluation.
    
    Instead, evaluate BACK at the beginning, before scalarization, add a check
    that the argument is present if necessary, and evaluate the resulting
    expression to a variable, before using the variable in the inline code.
    
    gcc/fortran/ChangeLog:
    
            * trans-intrinsic.cc (maybe_absent_optional_variable): New function.
            (gfc_conv_intrinsic_minmaxloc): Remove BACK from scalarization and
            evaluate it before.  Add a check that BACK is not null if the
            expression is an optional dummy.  Save the resulting expression to a
            variable.  Use the variable in the generated inline code.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/maxloc_6.f90: New test.
            * gfortran.dg/minloc_7.f90: New test.

Diff:
---
 gcc/fortran/trans-intrinsic.cc         |  83 ++++++--
 gcc/testsuite/gfortran.dg/maxloc_6.f90 | 366 +++++++++++++++++++++++++++++++++
 gcc/testsuite/gfortran.dg/minloc_7.f90 | 366 +++++++++++++++++++++++++++++++++
 3 files changed, 801 insertions(+), 14 deletions(-)

diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index 180d0d7a88c6..150cb9ff963b 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -5209,6 +5209,50 @@ gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * 
expr)
 }
 
 
+/* Tells whether the expression E is a reference to an optional variable whose
+   presence is not known at compile time.  Those are variable references 
without
+   subreference; if there is a subreference, we can assume the variable is
+   present.  We have to special case full arrays, which we represent with a 
fake
+   "full" reference, and class descriptors for which a reference to data is not
+   really a subreference.  */
+
+bool
+maybe_absent_optional_variable (gfc_expr *e)
+{
+  if (!(e && e->expr_type == EXPR_VARIABLE))
+    return false;
+
+  gfc_symbol *sym = e->symtree->n.sym;
+  if (!sym->attr.optional)
+    return false;
+
+  gfc_ref *ref = e->ref;
+  if (ref == nullptr)
+    return true;
+
+  if (ref->type == REF_ARRAY
+      && ref->u.ar.type == AR_FULL
+      && ref->next == nullptr)
+    return true;
+
+  if (!(sym->ts.type == BT_CLASS
+       && ref->type == REF_COMPONENT
+       && ref->u.c.component == CLASS_DATA (sym)))
+    return false;
+
+  gfc_ref *next_ref = ref->next;
+  if (next_ref == nullptr)
+    return true;
+
+  if (next_ref->type == REF_ARRAY
+      && next_ref->u.ar.type == AR_FULL
+      && next_ref->next == nullptr)
+    return true;
+
+  return false;
+}
+
+
 /* Remove unneeded kind= argument from actual argument list when the
    result conversion is dealt with in a different place.  */
 
@@ -5321,11 +5365,11 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * 
expr, enum tree_code op)
   tree nonempty;
   tree lab1, lab2;
   tree b_if, b_else;
+  tree back;
   gfc_loopinfo loop;
   gfc_actual_arglist *actual;
   gfc_ss *arrayss;
   gfc_ss *maskss;
-  gfc_ss *backss;
   gfc_se arrayse;
   gfc_se maskse;
   gfc_expr *arrayexpr;
@@ -5391,10 +5435,29 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * 
expr, enum tree_code op)
     && maskexpr->symtree->n.sym->attr.dummy
     && maskexpr->symtree->n.sym->attr.optional;
   backexpr = actual->next->next->expr;
-  if (backexpr)
-    backss = gfc_get_scalar_ss (gfc_ss_terminator, backexpr);
+
+  gfc_init_se (&backse, NULL);
+  if (backexpr == nullptr)
+    back = logical_false_node;
+  else if (maybe_absent_optional_variable (backexpr))
+    {
+      /* This should have been checked already by
+        maybe_absent_optional_variable.  */
+      gcc_checking_assert (backexpr->expr_type == EXPR_VARIABLE);
+
+      gfc_conv_expr (&backse, backexpr);
+      tree present = gfc_conv_expr_present (backexpr->symtree->n.sym, false);
+      back = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
+                             logical_type_node, present, backse.expr);
+    }
   else
-    backss = nullptr;
+    {
+      gfc_conv_expr (&backse, backexpr);
+      back = backse.expr;
+    }
+  gfc_add_block_to_block (&se->pre, &backse.pre);
+  back = gfc_evaluate_now_loc (input_location, back, &se->pre);
+  gfc_add_block_to_block (&se->pre, &backse.post);
 
   nonempty = NULL;
   if (maskexpr && maskexpr->rank != 0)
@@ -5455,9 +5518,6 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * 
expr, enum tree_code op)
   if (maskss)
     gfc_add_ss_to_loop (&loop, maskss);
 
-  if (backss)
-    gfc_add_ss_to_loop (&loop, backss);
-
   gfc_add_ss_to_loop (&loop, arrayss);
 
   /* Initialize the loop.  */
@@ -5543,11 +5603,6 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * 
expr, enum tree_code op)
   gfc_conv_expr_val (&arrayse, arrayexpr);
   gfc_add_block_to_block (&block, &arrayse.pre);
 
-  gfc_init_se (&backse, NULL);
-  backse.ss = backss;
-  gfc_conv_expr_val (&backse, backexpr);
-  gfc_add_block_to_block (&block, &backse.pre);
-
   /* We do the following if this is a more extreme value.  */
   gfc_start_block (&ifblock);
 
@@ -5608,7 +5663,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * 
expr, enum tree_code op)
          elsebody2 = gfc_finish_block (&elseblock);
 
          tmp = fold_build3_loc (input_location, COND_EXPR, logical_type_node,
-                                backse.expr, ifbody2, elsebody2);
+                                back, ifbody2, elsebody2);
 
          gfc_add_expr_to_block (&block, tmp);
        }
@@ -5707,7 +5762,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * 
expr, enum tree_code op)
        elsebody2 = gfc_finish_block (&elseblock);
 
        tmp = fold_build3_loc (input_location, COND_EXPR, logical_type_node,
-                              backse.expr, ifbody2, elsebody2);
+                              back, ifbody2, elsebody2);
       }
 
       gfc_add_expr_to_block (&block, tmp);
diff --git a/gcc/testsuite/gfortran.dg/maxloc_6.f90 
b/gcc/testsuite/gfortran.dg/maxloc_6.f90
new file mode 100644
index 000000000000..d5439b8dca04
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/maxloc_6.f90
@@ -0,0 +1,366 @@
+! { dg-do run }
+!
+! Check that the inline implementation of MAXLOC correctly supports indirect
+! MASK, that is a MASK expression that is itself an optional variable.
+
+program p
+  implicit none
+  integer, parameter :: data(*) = (/ 3, 7, 1, 0, 7, 0, 3, 5, 3, 0 /)
+  logical, parameter :: mask(*) = (/ .true. , .false., .true., .true. , &
+                                   & .false., .true. , .true., .false., &
+                                   & .true. , .true. /)
+  call check_int_const_shape_absent_back
+  call check_int_const_shape_false_back
+  call check_int_const_shape_true_back
+  call check_int_const_shape_scalar_mask_absent_back
+  call check_int_const_shape_scalar_mask_false_back
+  call check_int_const_shape_scalar_mask_true_back
+  call check_int_assumed_shape_absent_back
+  call check_int_assumed_shape_false_back
+  call check_int_assumed_shape_true_back
+  call check_int_assumed_shape_scalar_mask_absent_back
+  call check_int_assumed_shape_scalar_mask_false_back
+  call check_int_assumed_shape_scalar_mask_true_back
+  call check_int_func_absent_back
+  call check_int_func_false_back
+  call check_int_func_true_back
+  call check_int_func_scalar_mask_absent_back
+  call check_int_func_scalar_mask_false_back
+  call check_int_func_scalar_mask_true_back
+  call check_int_const_shape_array_mask_absent_back
+  call check_int_const_shape_array_mask_false_back
+  call check_int_const_shape_array_mask_true_back
+  call check_int_assumed_shape_array_mask_absent_back
+  call check_int_assumed_shape_array_mask_false_back
+  call check_int_assumed_shape_array_mask_true_back
+  call check_real_const_shape_absent_back
+  call check_real_const_shape_false_back
+  call check_real_const_shape_true_back
+  call check_real_const_shape_scalar_mask_absent_back
+  call check_real_const_shape_scalar_mask_false_back
+  call check_real_const_shape_scalar_mask_true_back
+  call check_real_assumed_shape_absent_back
+  call check_real_assumed_shape_false_back
+  call check_real_assumed_shape_true_back
+  call check_real_assumed_shape_scalar_mask_absent_back
+  call check_real_assumed_shape_scalar_mask_false_back
+  call check_real_assumed_shape_scalar_mask_true_back
+contains
+  subroutine call_maxloc_int_const_shape(r, a, b)
+    integer :: r, a(10)
+    logical, optional :: b
+    r = maxloc(a, dim = 1, back = b)
+  end subroutine
+  subroutine check_int_const_shape_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_const_shape(r, a)
+    if (r /= 2) stop 9
+  end subroutine
+  subroutine check_int_const_shape_false_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_const_shape(r, a, .false.)
+    if (r /= 2) stop 16
+  end subroutine
+  subroutine check_int_const_shape_true_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_const_shape(r, a, .true.)
+    if (r /= 5) stop 23
+  end subroutine
+  subroutine call_maxloc_int_const_shape_scalar_mask(r, a, m, b)
+    integer :: r, a(10)
+    logical :: m
+    logical, optional :: b
+    r = maxloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_const_shape_scalar_mask_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_const_shape_scalar_mask(r, a, .true.)
+    if (r /= 2) stop 30
+  end subroutine
+  subroutine check_int_const_shape_scalar_mask_false_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_const_shape_scalar_mask(r, a, .true., .false.)
+    if (r /= 2) stop 37
+  end subroutine
+  subroutine check_int_const_shape_scalar_mask_true_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_const_shape_scalar_mask(r, a, .true., .true.)
+    if (r /= 5) stop 44
+  end subroutine
+  subroutine call_maxloc_int_assumed_shape(r, a, b)
+    integer :: r, a(:)
+    logical, optional :: b
+    r = maxloc(a, dim = 1, back = b)
+  end subroutine
+  subroutine check_int_assumed_shape_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_assumed_shape(r, a)
+    if (r /= 2) stop 51
+  end subroutine
+  subroutine check_int_assumed_shape_false_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_assumed_shape(r, a, .false.)
+    if (r /= 2) stop 58
+  end subroutine
+  subroutine check_int_assumed_shape_true_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_assumed_shape(r, a, .true.)
+    if (r /= 5) stop 65
+  end subroutine
+  subroutine call_maxloc_int_assumed_shape_scalar_mask(r, a, m, b)
+    integer :: r, a(:)
+    logical :: m
+    logical, optional :: b
+    r = maxloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_assumed_shape_scalar_mask_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_assumed_shape_scalar_mask(r, a, .true.)
+    if (r /= 2) stop 72
+  end subroutine
+  subroutine check_int_assumed_shape_scalar_mask_false_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_assumed_shape_scalar_mask(r, a, .true., .false.)
+    if (r /= 2) stop 79
+  end subroutine
+  subroutine check_int_assumed_shape_scalar_mask_true_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_assumed_shape_scalar_mask(r, a, .true., .true.)
+    if (r /= 5) stop 86
+  end subroutine
+  function id(a) result(r)
+    integer, dimension(:) :: a
+    integer, dimension(size(a, dim = 1)) :: r
+    r = a
+  end function
+  subroutine call_maxloc_int_func(r, a, b)
+    integer :: r, a(:)
+    logical, optional :: b
+    r = maxloc(id(a) + 1, dim = 1, back = b)
+  end subroutine
+  subroutine check_int_func_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_func(r, a)
+    if (r /= 2) stop 93
+  end subroutine
+  subroutine check_int_func_false_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_func(r, a, .false.)
+    if (r /= 2) stop 100
+  end subroutine
+  subroutine check_int_func_true_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_func(r, a, .true.)
+    if (r /= 5) stop 107
+  end subroutine
+  subroutine call_maxloc_int_func_scalar_mask(r, a, m, b)
+    integer :: r, a(:)
+    logical :: m
+    logical, optional :: b
+    r = maxloc(id(a) + 1, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_func_scalar_mask_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_func_scalar_mask(r, a, .true.)
+    if (r /= 2) stop 114
+  end subroutine
+  subroutine check_int_func_scalar_mask_false_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_func_scalar_mask(r, a, .true., .false.)
+    if (r /= 2) stop 121
+  end subroutine
+  subroutine check_int_func_scalar_mask_true_back
+    integer :: r, a(10)
+    a = data
+    call call_maxloc_int_func_scalar_mask(r, a, .true., .true.)
+    if (r /= 5) stop 128
+  end subroutine
+  subroutine call_maxloc_int_const_shape_array_mask(r, a, m, b)
+    integer :: r, a(10)
+    logical :: m(10)
+    logical, optional :: b
+    r = maxloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_const_shape_array_mask_absent_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_maxloc_int_const_shape_array_mask(r, a, m)
+    if (r /= 1) stop 135
+  end subroutine
+  subroutine check_int_const_shape_array_mask_false_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_maxloc_int_const_shape_array_mask(r, a, m, .false.)
+    if (r /= 1) stop 142
+  end subroutine
+  subroutine check_int_const_shape_array_mask_true_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_maxloc_int_const_shape_array_mask(r, a, m, .true.)
+    if (r /= 9) stop 149
+  end subroutine
+  subroutine call_maxloc_int_assumed_shape_array_mask(r, a, m, b)
+    integer :: r, a(:)
+    logical :: m(:)
+    logical, optional :: b
+    r = maxloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_assumed_shape_array_mask_absent_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_maxloc_int_assumed_shape_array_mask(r, a, m)
+    if (r /= 1) stop 156
+  end subroutine
+  subroutine check_int_assumed_shape_array_mask_false_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_maxloc_int_assumed_shape_array_mask(r, a, m, .false.)
+    if (r /= 1) stop 163
+  end subroutine
+  subroutine check_int_assumed_shape_array_mask_true_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_maxloc_int_assumed_shape_array_mask(r, a, m, .true.)
+    if (r /= 9) stop 170
+  end subroutine
+  subroutine call_maxloc_real_const_shape(r, a, b)
+    integer :: r
+    real :: a(10)
+    logical, optional :: b
+    r = maxloc(a, dim = 1, back = b)
+  end subroutine
+  subroutine check_real_const_shape_absent_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_maxloc_real_const_shape(r, a)
+    if (r /= 2) stop 177
+  end subroutine
+  subroutine check_real_const_shape_false_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_maxloc_real_const_shape(r, a, .false.)
+    if (r /= 2) stop 184
+  end subroutine
+  subroutine check_real_const_shape_true_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_maxloc_real_const_shape(r, a, .true.)
+    if (r /= 5) stop 191
+  end subroutine
+  subroutine call_maxloc_real_const_shape_scalar_mask(r, a, m, b)
+    integer :: r
+    real :: a(10)
+    logical :: m
+    logical, optional :: b
+    r = maxloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_real_const_shape_scalar_mask_absent_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_maxloc_real_const_shape_scalar_mask(r, a, .true.)
+    if (r /= 2) stop 198
+  end subroutine
+  subroutine check_real_const_shape_scalar_mask_false_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_maxloc_real_const_shape_scalar_mask(r, a, .true., .false.)
+    if (r /= 2) stop 205
+  end subroutine
+  subroutine check_real_const_shape_scalar_mask_true_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_maxloc_real_const_shape_scalar_mask(r, a, .true., .true.)
+    if (r /= 5) stop 212
+  end subroutine
+  subroutine call_maxloc_real_assumed_shape(r, a, b)
+    integer :: r
+    real :: a(:)
+    logical, optional :: b
+    r = maxloc(a, dim = 1, back = b)
+  end subroutine
+  subroutine check_real_assumed_shape_absent_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_maxloc_real_assumed_shape(r, a)
+    if (r /= 2) stop 219
+  end subroutine
+  subroutine check_real_assumed_shape_false_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_maxloc_real_assumed_shape(r, a, .false.)
+    if (r /= 2) stop 226
+  end subroutine
+  subroutine check_real_assumed_shape_true_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_maxloc_real_assumed_shape(r, a, .true.)
+    if (r /= 5) stop 233
+  end subroutine
+  subroutine call_maxloc_real_assumed_shape_scalar_mask(r, a, m, b)
+    integer :: r
+    real :: a(:)
+    logical :: m
+    logical, optional :: b
+    r = maxloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_real_assumed_shape_scalar_mask_absent_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_maxloc_real_assumed_shape_scalar_mask(r, a, .true.)
+    if (r /= 2) stop 240
+  end subroutine
+  subroutine check_real_assumed_shape_scalar_mask_false_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_maxloc_real_assumed_shape_scalar_mask(r, a, .true., .false.)
+    if (r /= 2) stop 247
+  end subroutine
+  subroutine check_real_assumed_shape_scalar_mask_true_back
+    integer :: r
+    real :: a(10)
+    a = data
+    a = (/ real :: data /)
+    call call_maxloc_real_assumed_shape_scalar_mask(r, a, .true., .true.)
+    if (r /= 5) stop 254
+  end subroutine
+end program p
diff --git a/gcc/testsuite/gfortran.dg/minloc_7.f90 
b/gcc/testsuite/gfortran.dg/minloc_7.f90
new file mode 100644
index 000000000000..7da77faaa010
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/minloc_7.f90
@@ -0,0 +1,366 @@
+! { dg-do run }
+!
+! Check that the inline implementation of MINLOC correctly supports indirect
+! MASK, that is a MASK expression that is itself an optional variable.
+
+program p
+  implicit none
+  integer, parameter :: data(*) = (/ 6, 2, 8, 9, 2, 9, 6, 4, 6, 9 /)
+  logical, parameter :: mask(*) = (/ .true. , .false., .true., .true. , &
+                                   & .false., .true. , .true., .false., &
+                                   & .true. , .true. /)
+  call check_int_const_shape_absent_back
+  call check_int_const_shape_false_back
+  call check_int_const_shape_true_back
+  call check_int_const_shape_scalar_mask_absent_back
+  call check_int_const_shape_scalar_mask_false_back
+  call check_int_const_shape_scalar_mask_true_back
+  call check_int_assumed_shape_absent_back
+  call check_int_assumed_shape_false_back
+  call check_int_assumed_shape_true_back
+  call check_int_assumed_shape_scalar_mask_absent_back
+  call check_int_assumed_shape_scalar_mask_false_back
+  call check_int_assumed_shape_scalar_mask_true_back
+  call check_int_func_absent_back
+  call check_int_func_false_back
+  call check_int_func_true_back
+  call check_int_func_scalar_mask_absent_back
+  call check_int_func_scalar_mask_false_back
+  call check_int_func_scalar_mask_true_back
+  call check_int_const_shape_array_mask_absent_back
+  call check_int_const_shape_array_mask_false_back
+  call check_int_const_shape_array_mask_true_back
+  call check_int_assumed_shape_array_mask_absent_back
+  call check_int_assumed_shape_array_mask_false_back
+  call check_int_assumed_shape_array_mask_true_back
+  call check_real_const_shape_absent_back
+  call check_real_const_shape_false_back
+  call check_real_const_shape_true_back
+  call check_real_const_shape_scalar_mask_absent_back
+  call check_real_const_shape_scalar_mask_false_back
+  call check_real_const_shape_scalar_mask_true_back
+  call check_real_assumed_shape_absent_back
+  call check_real_assumed_shape_false_back
+  call check_real_assumed_shape_true_back
+  call check_real_assumed_shape_scalar_mask_absent_back
+  call check_real_assumed_shape_scalar_mask_false_back
+  call check_real_assumed_shape_scalar_mask_true_back
+contains
+  subroutine call_minloc_int_const_shape(r, a, b)
+    integer :: r, a(10)
+    logical, optional :: b
+    r = minloc(a, dim = 1, back = b)
+  end subroutine
+  subroutine check_int_const_shape_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_const_shape(r, a)
+    if (r /= 2) stop 9
+  end subroutine
+  subroutine check_int_const_shape_false_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_const_shape(r, a, .false.)
+    if (r /= 2) stop 16
+  end subroutine
+  subroutine check_int_const_shape_true_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_const_shape(r, a, .true.)
+    if (r /= 5) stop 23
+  end subroutine
+  subroutine call_minloc_int_const_shape_scalar_mask(r, a, m, b)
+    integer :: r, a(10)
+    logical :: m
+    logical, optional :: b
+    r = minloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_const_shape_scalar_mask_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_const_shape_scalar_mask(r, a, .true.)
+    if (r /= 2) stop 30
+  end subroutine
+  subroutine check_int_const_shape_scalar_mask_false_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_const_shape_scalar_mask(r, a, .true., .false.)
+    if (r /= 2) stop 37
+  end subroutine
+  subroutine check_int_const_shape_scalar_mask_true_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_const_shape_scalar_mask(r, a, .true., .true.)
+    if (r /= 5) stop 44
+  end subroutine
+  subroutine call_minloc_int_assumed_shape(r, a, b)
+    integer :: r, a(:)
+    logical, optional :: b
+    r = minloc(a, dim = 1, back = b)
+  end subroutine
+  subroutine check_int_assumed_shape_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_assumed_shape(r, a)
+    if (r /= 2) stop 51
+  end subroutine
+  subroutine check_int_assumed_shape_false_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_assumed_shape(r, a, .false.)
+    if (r /= 2) stop 58
+  end subroutine
+  subroutine check_int_assumed_shape_true_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_assumed_shape(r, a, .true.)
+    if (r /= 5) stop 65
+  end subroutine
+  subroutine call_minloc_int_assumed_shape_scalar_mask(r, a, m, b)
+    integer :: r, a(:)
+    logical :: m
+    logical, optional :: b
+    r = minloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_assumed_shape_scalar_mask_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_assumed_shape_scalar_mask(r, a, .true.)
+    if (r /= 2) stop 72
+  end subroutine
+  subroutine check_int_assumed_shape_scalar_mask_false_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_assumed_shape_scalar_mask(r, a, .true., .false.)
+    if (r /= 2) stop 79
+  end subroutine
+  subroutine check_int_assumed_shape_scalar_mask_true_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_assumed_shape_scalar_mask(r, a, .true., .true.)
+    if (r /= 5) stop 86
+  end subroutine
+  function id(a) result(r)
+    integer, dimension(:) :: a
+    integer, dimension(size(a, dim = 1)) :: r
+    r = a
+  end function
+  subroutine call_minloc_int_func(r, a, b)
+    integer :: r, a(:)
+    logical, optional :: b
+    r = minloc(id(a) + 1, dim = 1, back = b)
+  end subroutine
+  subroutine check_int_func_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_func(r, a)
+    if (r /= 2) stop 93
+  end subroutine
+  subroutine check_int_func_false_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_func(r, a, .false.)
+    if (r /= 2) stop 100
+  end subroutine
+  subroutine check_int_func_true_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_func(r, a, .true.)
+    if (r /= 5) stop 107
+  end subroutine
+  subroutine call_minloc_int_func_scalar_mask(r, a, m, b)
+    integer :: r, a(:)
+    logical :: m
+    logical, optional :: b
+    r = minloc(id(a) + 1, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_func_scalar_mask_absent_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_func_scalar_mask(r, a, .true.)
+    if (r /= 2) stop 114
+  end subroutine
+  subroutine check_int_func_scalar_mask_false_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_func_scalar_mask(r, a, .true., .false.)
+    if (r /= 2) stop 121
+  end subroutine
+  subroutine check_int_func_scalar_mask_true_back
+    integer :: r, a(10)
+    a = data
+    call call_minloc_int_func_scalar_mask(r, a, .true., .true.)
+    if (r /= 5) stop 128
+  end subroutine
+  subroutine call_minloc_int_const_shape_array_mask(r, a, m, b)
+    integer :: r, a(10)
+    logical :: m(10)
+    logical, optional :: b
+    r = minloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_const_shape_array_mask_absent_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_minloc_int_const_shape_array_mask(r, a, m)
+    if (r /= 1) stop 135
+  end subroutine
+  subroutine check_int_const_shape_array_mask_false_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_minloc_int_const_shape_array_mask(r, a, m, .false.)
+    if (r /= 1) stop 142
+  end subroutine
+  subroutine check_int_const_shape_array_mask_true_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_minloc_int_const_shape_array_mask(r, a, m, .true.)
+    if (r /= 9) stop 149
+  end subroutine
+  subroutine call_minloc_int_assumed_shape_array_mask(r, a, m, b)
+    integer :: r, a(:)
+    logical :: m(:)
+    logical, optional :: b
+    r = minloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_assumed_shape_array_mask_absent_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_minloc_int_assumed_shape_array_mask(r, a, m)
+    if (r /= 1) stop 156
+  end subroutine
+  subroutine check_int_assumed_shape_array_mask_false_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_minloc_int_assumed_shape_array_mask(r, a, m, .false.)
+    if (r /= 1) stop 163
+  end subroutine
+  subroutine check_int_assumed_shape_array_mask_true_back
+    integer :: r, a(10)
+    logical :: m(10)
+    a = data
+    m = mask
+    call call_minloc_int_assumed_shape_array_mask(r, a, m, .true.)
+    if (r /= 9) stop 170
+  end subroutine
+  subroutine call_minloc_real_const_shape(r, a, b)
+    integer :: r
+    real :: a(10)
+    logical, optional :: b
+    r = minloc(a, dim = 1, back = b)
+  end subroutine
+  subroutine check_real_const_shape_absent_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_minloc_real_const_shape(r, a)
+    if (r /= 2) stop 177
+  end subroutine
+  subroutine check_real_const_shape_false_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_minloc_real_const_shape(r, a, .false.)
+    if (r /= 2) stop 184
+  end subroutine
+  subroutine check_real_const_shape_true_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_minloc_real_const_shape(r, a, .true.)
+    if (r /= 5) stop 191
+  end subroutine
+  subroutine call_minloc_real_const_shape_scalar_mask(r, a, m, b)
+    integer :: r
+    real :: a(10)
+    logical :: m
+    logical, optional :: b
+    r = minloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_real_const_shape_scalar_mask_absent_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_minloc_real_const_shape_scalar_mask(r, a, .true.)
+    if (r /= 2) stop 198
+  end subroutine
+  subroutine check_real_const_shape_scalar_mask_false_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_minloc_real_const_shape_scalar_mask(r, a, .true., .false.)
+    if (r /= 2) stop 205
+  end subroutine
+  subroutine check_real_const_shape_scalar_mask_true_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_minloc_real_const_shape_scalar_mask(r, a, .true., .true.)
+    if (r /= 5) stop 212
+  end subroutine
+  subroutine call_minloc_real_assumed_shape(r, a, b)
+    integer :: r
+    real :: a(:)
+    logical, optional :: b
+    r = minloc(a, dim = 1, back = b)
+  end subroutine
+  subroutine check_real_assumed_shape_absent_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_minloc_real_assumed_shape(r, a)
+    if (r /= 2) stop 219
+  end subroutine
+  subroutine check_real_assumed_shape_false_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_minloc_real_assumed_shape(r, a, .false.)
+    if (r /= 2) stop 226
+  end subroutine
+  subroutine check_real_assumed_shape_true_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_minloc_real_assumed_shape(r, a, .true.)
+    if (r /= 5) stop 233
+  end subroutine
+  subroutine call_minloc_real_assumed_shape_scalar_mask(r, a, m, b)
+    integer :: r
+    real :: a(:)
+    logical :: m
+    logical, optional :: b
+    r = minloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_real_assumed_shape_scalar_mask_absent_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_minloc_real_assumed_shape_scalar_mask(r, a, .true.)
+    if (r /= 2) stop 240
+  end subroutine
+  subroutine check_real_assumed_shape_scalar_mask_false_back
+    integer :: r
+    real :: a(10)
+    a = (/ real :: data /)
+    call call_minloc_real_assumed_shape_scalar_mask(r, a, .true., .false.)
+    if (r /= 2) stop 247
+  end subroutine
+  subroutine check_real_assumed_shape_scalar_mask_true_back
+    integer :: r
+    real :: a(10)
+    a = data
+    a = (/ real :: data /)
+    call call_minloc_real_assumed_shape_scalar_mask(r, a, .true., .true.)
+    if (r /= 5) stop 254
+  end subroutine
+end program p

Reply via email to