public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
From: Mikael Morin <morin-mikael@orange.fr>
To: sgk@troutmask.apl.washington.edu
Cc: gfortran <fortran@gcc.gnu.org>
Subject: Re: typespec in forall and implied-do
Date: Sun, 27 Nov 2022 20:33:55 +0100	[thread overview]
Message-ID: <b9c87b8b-3e4f-5f17-3221-414d0ff6b3cc@orange.fr> (raw)
In-Reply-To: <db6b7135-111b-fc6c-e120-5fb4653964a4@orange.fr>

Le 27/11/2022 à 20:17, Mikael Morin a écrit :
> Le 21/11/2022 à 19:46, Steve Kargl a écrit :
>> On Mon, Nov 21, 2022 at 11:34:07AM +0100, Mikael Morin wrote:
>>> Le 21/11/2022 à 00:31, Steve Kargl via Fortran a écrit :
>>>>
>>>> Unfortunately, gfortran does not define a namespace for an implied-do
>>>> index and uses a kludge by adding the attr.implied_index attribute to
>>>> the symbol.  Unfortunately**2, gfortran uses gfc_match_iterator for
>>>> all places that 'i = start, stop [,step]' and there is no way to know
>>>> if what is being parsed.  With the introduction of an optional 
>>>> typespec,
>>>> there is no easy way to deal with it in a clean way.  Things get messy
>>>> quickly when trying to deal with implicit typing and explicitly typed
>>>> symbols.  So, if the implied-do index has previously been typed such as
>>>>
>>>>       integer(8) i
>>>>       print *, (i, integer(2) i=1, 3)
>>>>
>>>> the integer(2) is ignored.  That's this part of the gfc_match_iterator
>>>> diff
>>>>
>>>> +  if (seen_ts && var->ts.type == BT_UNKNOWN)
>>>> +    {
>>>> +      var->ts.type = ts.type;
>>>> +      var->ts.kind = ts.kind;
>>>> +      var->symtree->n.sym->ts.type = ts.type;
>>>> +      var->symtree->n.sym->ts.kind = ts.kind;
>>>> +    }
>>>>
>>>> Perhaps, a better way would be to simply create a shadow symbol
>>>> if a typespec appears in an iterator
>>>>
>>>>       print *, (i, integer i=1,3)
>>>>
>>>> would become
>>>>
>>>>       print *, (_i, integer _i=1,3)
>>>>
>>>> The issue is then that implied-do object list needs to be walked
>>>> and all occurrence of i must be replaced with _i.
>>>>
>>> Or maybe a namespace could be created if seen_ts is true?
>>
>> Yes, I thought about creating a new namespace, but I don't
>> have too much experience on how to deal with them.  Even
>> with a new namespace, we have to deal with an implied-do
>> loop in an initialization expression.  At the moment,
>> gfc_reduce_init_expr() does recognize some (all?) implied-do
>> loops.
>>
>> This is legal code, which uses implicit typing.  Here,
>> I get an integer type, but gfc_reduce_init_expr() rejects
>> the construct.
>>
>> program foo
>>     use iso_fortran_env, only : k => real_kinds
>>     integer, parameter :: n = size(k)
>>     integer, parameter ::p(n) = [(digits(real(1.,k(i))),i = 1,n)]
>>     print '(*(I0,X))', p
>> end program foo
>>
>> % gfortran -o z a.f90
>> a.f90:6:30:
>>
>>      6 |    &  p(n) = [(digits(real(1.,k(i))),  i = 1, n)]
>>        |                              1
>> Error: Invalid kind for REAL at (1)
>>
> I have looked at it, it is a tricky bug.
> 
> The first step of gfc_check_init_expr, way before trying to expand the 
> array constructor, is to resolve it.  Resolution of the array 
> constructor needs resolution of the ac-value expression, which needs 
> resolution of the real(...) expression.  Resolution of that expression 
> calls gfc_check_real, which checks that the KIND argument is a valid 
> kind, which means among other things being constant, and being able to 
> extract its value to check it against the list of defined kinds for the 
> platform.  And we can't extract its value before the expansion of the 
> array constructor, so the error is emitted, which prevents array 
> constructor expansion later on.
> 
> So it's a kind of chicken and egg problem.
> Right now, I don't see any solution (except simply removing the error).

With the following patch, no error is reported in case of failure of 
gfc_extract_int.  As the constantness and type checks have been 
redundantly checked in kind_check before the call to gfc_extract_int, we 
only miss to report an error if the value doesn't fit on a host int.  I 
think it's an acceptable loss.

diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 91d87a1b2c1..a8edeebe9cd 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -654,12 +654,14 @@ kind_check (gfc_expr *k, int n, bt type)
        return false;
      }

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

    return true;


This avoids emitting the error you were facing.
Unfortunately, the same error is caught later at a different place.

test.f90:4:48:

     4 |    integer, parameter ::p(n) = [(digits(real(1.,k(i))),i = 1,n)]
       |                                                1
Error: KIND parameter of REAL at (1) must be an initialization expression




  reply	other threads:[~2022-11-27 19:33 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-20 21:28 Harald Anlauf
2022-11-20 23:31 ` Steve Kargl
     [not found]   ` <d2efcc09-f5be-904e-fb70-f75fdabbee1f@orange.fr>
     [not found]     ` <Y3vHlojilLVU8qC2@troutmask.apl.washington.edu>
2022-11-27 19:17       ` Mikael Morin
2022-11-27 19:33         ` Mikael Morin [this message]
2022-11-20 23:33 ` Steve Kargl
2022-11-22 21:15 ` Harald Anlauf
2022-11-22 21:59   ` Steve Kargl
  -- strict thread matches above, loose matches on Subject: below --
2022-11-16  1:13 Steve Kargl
2022-11-16  2:31 ` Steve Kargl
2022-11-16 20:24   ` Steve Kargl
2022-11-16 18:08 ` Steve Kargl
2022-11-16 18:20 ` Steve Kargl
2022-11-16 21:30 ` Steve Kargl
2022-11-17  0:32   ` Steve Kargl
2022-11-17  0:47     ` Steve Kargl
2022-11-17  4:15       ` Steve Kargl
2022-11-17 18:48 ` Steve Kargl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b9c87b8b-3e4f-5f17-3221-414d0ff6b3cc@orange.fr \
    --to=morin-mikael@orange.fr \
    --cc=fortran@gcc.gnu.org \
    --cc=sgk@troutmask.apl.washington.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).