From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.smtpout.orange.fr (smtp-23.smtpout.orange.fr [80.12.242.23]) by sourceware.org (Postfix) with ESMTPS id 6EB063858D3C for ; Sun, 27 Nov 2022 19:33:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6EB063858D3C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=orange.fr Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=orange.fr Received: from [192.168.1.17] ([2.10.193.163]) by smtp.orange.fr with ESMTPA id zNPXongcv19qxzNPXosdxd; Sun, 27 Nov 2022 20:33:58 +0100 X-ME-Helo: [192.168.1.17] X-ME-Auth: bW9yaW4tbWlrYWVsQG9yYW5nZS5mcg== X-ME-Date: Sun, 27 Nov 2022 20:33:58 +0100 X-ME-IP: 2.10.193.163 Message-ID: Date: Sun, 27 Nov 2022 20:33:55 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.5.0 Subject: Re: typespec in forall and implied-do Content-Language: fr From: Mikael Morin To: sgk@troutmask.apl.washington.edu Cc: gfortran References: In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-8.5 required=5.0 tests=BAYES_00,BODY_8BITS,FREEMAIL_FROM,GIT_PATCH_0,JMQ_SPF_NEUTRAL,KAM_DMARC_STATUS,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: 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