[Bug fortran/91963] Logical function does not simplify

2019-10-03 Thread tkoenig at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91963

--- Comment #9 from Thomas Koenig  ---

(In reply to Thomas Koenig from comment #6)
> Somewhat reduced:
> 
> program main
>   integer, dimension(2), parameter :: n=[1,4]
>   logical, parameter :: a = logical(.true.,minval([(n(i),i=1,4)]))
> end program main
> 
> Even more reduced, without LOGICAL:
> 
> program main
>   integer, dimension(2), parameter :: n=[1,4]
>   integer, parameter :: m = minval([(n(i),i=1,4)],1)
> end program main

Both of these test cases are wrong, of course; there is no
n(3), nor is there a n(4).

The error message is bogus (which had me confused), an out-of-bounds-error
should be reported.

[Bug fortran/91963] Logical function does not simplify

2019-10-02 Thread sgk at troutmask dot apl.washington.edu
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91963

--- Comment #8 from Steve Kargl  ---
On Wed, Oct 02, 2019 at 06:25:15PM +, sgk at troutmask dot
apl.washington.edu wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91963
> 
> --- Comment #7 from Steve Kargl  ---
> On Wed, Oct 02, 2019 at 06:10:48PM +, tkoenig at gcc dot gnu.org wrote:
> > 
> > You're right, Steve, the problem lies in the simplification
> > of the implied DO loop (the error message is a catch-all
> > which is somewhat misleading here).
> > 
> 
> I've looked at this a long time ago.  Never came up with a fix.
> 
> In the original code or the conforming example I posted, gfortran
> ends up in check.c(kind_check).  If we look at lines 630 and following
> we have
> 
>   if (!gfc_check_init_expr (k))
> {
>   gfc_error ("%qs argument of %qs intrinsic at %L must be a constant",
>   gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
>   >where);
>   return false;
> }
> 
> gfc_check_init_exp() returns ok, so gfortran knows it has an
> intialization expression.

Uing this testcase, one ends up in check.c(kind_check).

   use, intrinsic :: iso_fortran_env, only : logical_kinds
   integer :: i
   integer, parameter :: n = size(logical_kinds)
   logical, parameter :: m(*) = [(logical(.true.,logical_kinds(i)), i = 1, n)]
   print *, "logical_kinds = ", logical_kinds
   print *, "minkind = ", minkind
   end

(gdb) b gfc_check_logical
Breakpoint 1 at 0x756fa0: file ../../gccx/gcc/fortran/check.c, line 3529.
(gdb) run a.f90
Starting program:
/safe/sgk/work/x/libexec/gcc/x86_64-unknown-freebsd13.0/10.0.0/f951 a.f90

Breakpoint 1, gfc_check_logical (a=0x202de50a0, kind=0x202de5180)
at ../../gccx/gcc/fortran/check.c:3529
3529  if (!type_check (a, 0, BT_LOGICAL))
(gdb) n
3531  if (!kind_check (kind, 1, BT_LOGICAL))
(gdb) s
kind_check (k=0x202de5180, n=1, type=BT_LOGICAL)
at ../../gccx/gcc/fortran/check.c:612
612   int kind = 0;
 (gdb) n
614   if (k == NULL)
(gdb) n
620   if (!scalar_check (k, n))
(gdb) n
623   if (!gfc_check_init_expr (k))
(gdb) n
631   if (gfc_extract_int (k, )
(gdb) call debug(k)
MAIN__:logical_kinds(MAIN__:i) (INTEGER 4)
(gdb) p *k->shape
Cannot access memory at address 0x0
(gdb) p *k->ref
$5 = {type = REF_ARRAY, u = {ar = {type = AR_ELEMENT, dimen = 1, codimen = 0, 
  in_allocate = false, team = 0x0, stat = 0x0, where = {
nextc = 0x202323418, lb = 0x202323300}, as = 0x202debb40, c_where = {{
  nextc = 0x20232341c, lb = 0x202323300}, {nextc = 0x0, 
  lb = 0x0} }, start = {0x202de5260, 
0x0 }, end = {0x0 }, stride = {
0x0 }, dimen_type = {DIMEN_ELEMENT, 
0 }}, c = {component = 0x10002, sym = 0x0}, 
ss = {start = 0x10002, end = 0x0, length = 0x0}, i = INQUIRY_KIND}, 
  next = 0x0}
(gdb) p *k->value->constructor

k->ref seems to know we have an array element, but the constructor
is empty.

(gdb) call debug(k->symtree->n.sym->value)
(/ 1 , 2 , 4 , 8 , 16 /) (INTEGER 4)

So the information is in the symtree.

(gdb) p *k->symtree->n.sym->value
$6 = {expr_type = EXPR_ARRAY, ts = {type = BT_INTEGER, kind = 4, u = {
  derived = 0x0, cl = 0x0, pad = 0}, interface = 0x0, is_c_interop = 0, 
is_iso_c = 0, f90_type = BT_UNKNOWN, deferred = false, 
interop_kind = 0x0}, rank = 1, shape = 0x203706a10, symtree = 0x0, 
  ref = 0x0, where = {nextc = 0x0, lb = 0x0}, base_expr = 0x0, is_snan = 0, 
  error = 0, user_operator = 0, mold = 0, must_finalize = 0, 
  no_bounds_check = 0, external_blas = 0, do_not_resolve_again = 0, 
  do_not_warn = 0, representation = {length = 0, string = 0x0}, boz = {
len = 0, rdx = 0, str = 0x0}, value = {logical = 48213696, 
iokind = 48213696, integer = {{_mp_alloc = 48213696, _mp_size = 2, 
_mp_d = 0x0}}, real = {{_mpfr_prec = 8638148288, _mpfr_sign = 0, 
_mpfr_exp = 0, _mpfr_d = 0x0}}, complex = {{re = {{
_mpfr_prec = 8638148288, _mpfr_sign = 0, _mpfr_exp = 0, 
_mpfr_d = 0x0}}, im = {{_mpfr_prec = 0, _mpfr_sign = 0, 
_mpfr_exp = 0, _mpfr_d = 0x0, op = {op = 48213696, uop = 0x0, 
  op1 = 0x0, op2 = 0x0}, function = {actual = 0x202dfaec0, name = 0x0, 
  isym = 0x0, esym = 0x0}, compcall = {actual = 0x202dfaec0, name = 0x0, 
  base_object = 0x0, tbp = 0x0, ignore_pass = 0, assign = 0}, character = {
  length = 8638148288, string = 0x0}, constructor = 0x202dfaec0}, 
  param_list = 0x0}

(gdb) p k->symtree->n.sym->attr.flavor
$9 = FL_PARAMETER

We have shape and constrcutor here, so we should be able to 
retrieve the array element value.

[Bug fortran/91963] Logical function does not simplify

2019-10-02 Thread sgk at troutmask dot apl.washington.edu
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91963

--- Comment #7 from Steve Kargl  ---
On Wed, Oct 02, 2019 at 06:10:48PM +, tkoenig at gcc dot gnu.org wrote:
> 
> You're right, Steve, the problem lies in the simplification
> of the implied DO loop (the error message is a catch-all
> which is somewhat misleading here).
> 

I've looked at this a long time ago.  Never came up with a fix.

In the original code or the conforming example I posted, gfortran
ends up in check.c(kind_check).  If we look at lines 630 and following
we have

  if (!gfc_check_init_expr (k))
{
  gfc_error ("%qs argument of %qs intrinsic at %L must be a constant",
  gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
  >where);
  return false;
}

gfc_check_init_exp() returns ok, so gfortran knows it has an
intialization expression.  It simply hasn't reduced it to a
constant.  The next section of code fails, because extraction
of the kind value fails.

  if (gfc_extract_int (k, )
  || gfc_validate_kind (type, kind, true) < 0)
{
  gfc_error ("Invalid kind for %s at %L", gfc_basic_typename (type),
   >where);
  return false;
}

This is were I'm stuck.  I think we need to rummage through
gfc_reduce_init_expr().

[Bug fortran/91963] Logical function does not simplify

2019-10-02 Thread tkoenig at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91963

Thomas Koenig  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2019-10-02
 Ever confirmed|0   |1

--- Comment #6 from Thomas Koenig  ---
Somewhat reduced:

program main
  integer, dimension(2), parameter :: n=[1,4]
  logical, parameter :: a = logical(.true.,minval([(n(i),i=1,4)]))
end program main

Even more reduced, without LOGICAL:

program main
  integer, dimension(2), parameter :: n=[1,4]
  integer, parameter :: m = minval([(n(i),i=1,4)],1)
end program main

log.f90:3:27:

3 |   integer, parameter :: m = minval([(n(i),i=1,4)],1)
  |   1
Error: transformational intrinsic 'minval' at (1) is not permitted in an
initialization expression

You're right, Steve, the problem lies in the simplification
of the implied DO loop (the error message is a catch-all
which is somewhat misleading here).

[Bug fortran/91963] Logical function does not simplify

2019-10-02 Thread sgk at troutmask dot apl.washington.edu
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91963

--- Comment #5 from Steve Kargl  ---
On Wed, Oct 02, 2019 at 07:07:08AM -0700, Steve Kargl wrote:
> On Wed, Oct 02, 2019 at 02:03:21PM +, kargl at gcc dot gnu.org wrote:
> > --- Comment #3 from kargl at gcc dot gnu.org ---
> > (In reply to Richard Biener from comment #1)
> > > But is it valid fortran?
> > 
> > Yes.  It's valid.  gfortran has poor handling of implied-do loops
> > in initialization expression.
> > 
> 
> Actually, the testcase submitted here in BZ is the
> one of three posted in c.l.f that is invalid.  C_BOOL
> is the only interoperable type for ISO BIND C, so the
> use of C_SIZEOF is invalid.
> 

Here's valid code that shows the same problem

   use, intrinsic :: iso_fortran_env, only : logical_kinds
   integer :: i
   integer, parameter :: minkind = logical_kinds(minloc([( storage_size( &
   &   a=[ logical(.false., logical_kinds(i))] ), &
   &   i = 1, size(logical_kinds) )], dim=1))
   print *, "logical_kinds = ", logical_kinds
   print *, "minkind = ", minkind
end

[Bug fortran/91963] Logical function does not simplify

2019-10-02 Thread sgk at troutmask dot apl.washington.edu
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91963

--- Comment #4 from Steve Kargl  ---
On Wed, Oct 02, 2019 at 02:03:21PM +, kargl at gcc dot gnu.org wrote:
> --- Comment #3 from kargl at gcc dot gnu.org ---
> (In reply to Richard Biener from comment #1)
> > But is it valid fortran?
> 
> Yes.  It's valid.  gfortran has poor handling of implied-do loops
> in initialization expression.
> 

Actually, the testcase submitted here in BZ is the
one of three posted in c.l.f that is invalid.  C_BOOL
is the only interoperable type for ISO BIND C, so the
use of C_SIZEOF is invalid.

[Bug fortran/91963] Logical function does not simplify

2019-10-02 Thread kargl at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91963

kargl at gcc dot gnu.org changed:

   What|Removed |Added

 CC||kargl at gcc dot gnu.org

--- Comment #3 from kargl at gcc dot gnu.org ---
(In reply to Richard Biener from comment #1)
> But is it valid fortran?

Yes.  It's valid.  gfortran has poor handling of implied-do loops
in initialization expression.

[Bug fortran/91963] Logical function does not simplify

2019-10-02 Thread tkoenig at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91963

--- Comment #2 from Thomas Koenig  ---
(In reply to Richard Biener from comment #1)
> But is it valid fortran?

I had to check, but yes.

LOGICAL is an elemental type conversion function, which has only constant
arguments, so it should be simplified.

There are also simpler cases where this works as expected:

program main
  logical, parameter :: l1 = .true.
  logical, parameter :: l4 = logical(l1, 4)
end program main

As does this:

program main
  integer, parameter, dimension(1) :: ar = [4]
  logical, parameter :: l1 = .true.
  logical, parameter :: l4 = logical(l1, ar(1))
end program main

[Bug fortran/91963] Logical function does not simplify

2019-10-02 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91963

Richard Biener  changed:

   What|Removed |Added

   Keywords||rejects-valid

--- Comment #1 from Richard Biener  ---
But is it valid fortran?