From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) by sourceware.org (Postfix) with ESMTPS id 27F57385383D; Tue, 3 Aug 2021 21:17:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 27F57385383D X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from [79.251.12.40] ([79.251.12.40]) by web-mail.gmx.net (3c-app-gmx-bap07.server.lan [172.19.172.77]) (via HTTP); Tue, 3 Aug 2021 23:17:22 +0200 MIME-Version: 1.0 Message-ID: From: Harald Anlauf To: Harald Anlauf Cc: Tobias Burnus , Bernhard Reutner-Fischer , Harald Anlauf via Gcc-patches , fortran Subject: Re: [PATCH] PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514 Content-Type: multipart/mixed; boundary=abmob-2a647071-03a6-4e3e-a0af-86f3e8b9000c Date: Tue, 3 Aug 2021 23:17:22 +0200 Importance: normal Sensitivity: Normal In-Reply-To: References: <20210610122435.296a207d@nbbrfq> X-UI-Message-Type: mail X-Priority: 3 X-Provags-ID: V03:K1:peLMeOS7aQgNY5OQ5gt+scV1+PkudKLdgd5RDozKTSc7y39KY0BDyhaDol7euhaZChmXg Cq6rvZ/Vb8VX9Hk7cZkdB+aWsReEwxDwH9d2hZ+ArkpTzGFyCSkQZQw8tT3xG3/GWAqf6pavejW7 LHDzrlSxuz5cnfcyBQBuFzk3E9W+DAIa2/1eeapQlfRbo7XV3AmVDg00p2Djep0mMglXVINPIVsz eynWVoyJvs5zuDFMTVIk40KKzspckz1UcxbT3J/Zav7jnfRtYr10ttINUYRK5pdhKCbWn06oivXN mY= X-UI-Out-Filterresults: notjunk:1;V03:K0:ZnKvtCTGgr0=:gas+tIGkEcW2IBmEyLkU21 /+GUqnJ6KfG2pOANwru6Yy0yXu2xH3sKcbCdexgCcU5oTTJAcm136nDOUadEZ5Gyv1SpQaIPj F8DN6oDryddAGqfWSTXdvJ3iyNoavkH4GljS76GV7T+jT4ArgA+FApkCT6VG0+Bwd9a/qfKet Zm718AiAd9Vl1Rb42e/dKYDYuAweIp03E6a8cAbjCQR6ujeoI3sVLZoVk4+wjuOaS8c3BHA0n Cp1U5UyhDDmbGjvmUF7bQoiw1zzY4mppZtDYXAlAVeAlqrnSPuGOGuJsp/f632iRBJ+hfhXnm uPUmqRjQo7hI79lX6np4byKxE3SU9K1eXLqMVg1xS5NSEkG7e59P7Dq9rOno1jydHm258iKLl mYXM3rhtakTiYpfLDud0S52dCuU6koMqOEc3BFXRnF+k4KYbvrN3Dp0OnZbI+z9x/N1J0MU4C s2Uuy45D43AeGoskQ01csMgVvt7qUXpDtUyP5lu7PLDZwxc3dQTVQC5Ayr7hHEyCFNEcCtrPj gvm4Aehp86gpy66TurEghLH/Wxw1U3b1922TddBs3yiGpgWvWMOfEODljs05LnV/KEZGVzo+c fQYMNCMD/XGiOmbk9csspWx0dpSrAyZssPexmyIm+Q2s1hEsZ16T5AZbGEW0ykA0OQFlrN9tZ FveqljVFZEA8QeQ+9+TXDbJ6HJj4IHdJdTV5/UykyowskdJ1mnWyjYbJnUE8O1Itw2WYkLiXR 9j6EaaTr8gEAxhN95zrCJQJA2XA4FVeMNZsxLPcBU6myvTAlVXJjOsLdOcEJm7aty/JkAcyCb F0DLO3t2xua17zc0f4Tw09yw3SVNg== X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FROM, GIT_PATCH_0, KAM_NUMSUBJECT, KAM_SHORT, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: fortran@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Fortran mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Aug 2021 21:17:30 -0000 --abmob-2a647071-03a6-4e3e-a0af-86f3e8b9000c Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Here's now my third attempt to fix this PR, taking into account the comments by Tobias and Bernhard=2E > > On 10=2E06=2E21 20:52, Harald Anlauf via Fortran wrote: > > > +static bool > > > +substring_has_constant_len (gfc_expr *e) > > > +{ > > > + ptrdiff_t istart, iend; > > > + size_t length; > > > + bool equal_length =3D false; > > > + > > > + if (e->ts=2Etype !=3D BT_CHARACTER > > > + || !e->ref > > > + || e->ref->type !=3D REF_SUBSTRING > >=20 > > Is there a reason why you do not handle: > >=20 > > type t > > character(len=3D5) :: str1 > > character(len=3D:), allocatable :: str2 > > end type > > type(t) :: x > >=20 > > allocate(x%str2, source=3D"abd") > > if (len (x%str)) /=3D 1) =2E=2E=2E > > if (len (x%str2(1:2) /=3D 2) =2E=2E=2E > > etc=2E > >=20 > > Namely: Search the last_ref =3D expr->ref->next->next =2E=2E=2E? > > and then check that lastref? The mentioned search is now implemented=2E Note, however, that gfc_simplify_len still won't handle neither deferred strings nor their substrings=2E I think there is nothing to simplify at compile time here=2E Otherwise there would be a conflict/inconsistency with type parameter inquiry, see F2018:9=2E4=2E5(2): "A deferred type parameter of a pointer that is not associated or of an unallocated allocatable variable shall not be inquired about=2E" > > * * * > >=20 > > Slightly unrelated: I think the following does not violate > > F2018's R916 / C923 =E2=80=93 but is rejected, namely: > > R916 type-param-inquiry is designator % type-param-name > > the latter is 'len' or 'kind' for intrinsic types=2E And: > > R901 designator is =2E=2E=2E > > or substring > > But > >=20 > > character(len=3D5) :: str > > print *, str(1:3)%len > > end > >=20 > > fails with > >=20 > > 2 | print *, str(1:3)%len > > | 1 > > Error: Syntax error in PRINT statement at (1) > >=20 > >=20 > > Assuming you don't want to handle it, can you open a new PR? > > Thanks! I tried to look into this, but there appear to be several unrelated issues requiring a separate treatment=2E I therefore opened: https://gcc=2Egnu=2Eorg/bugzilla/show_bug=2Ecgi?id=3D101735 > > > + istart =3D gfc_mpz_get_hwi (e->ref->u=2Ess=2Estart->value=2Einteg= er); > > > + iend =3D gfc_mpz_get_hwi (e->ref->u=2Ess=2Eend->value=2Einteger); > > > + length =3D gfc_mpz_get_hwi (e->ref->u=2Ess=2Elength->length->valu= e=2Einteger); > > > + > > > + if (istart <=3D iend) > > > + { > > > + if (istart < 1) > > > + { > > > + gfc_error ("Substring start index (%ld) at %L below 1", > > > + (long) istart, &e->ref->u=2Ess=2Estart->where); > >=20 > > As mentioned by Bernhard, you could use HOST_WIDE_INT_PRINT_DEC=2E > >=20 > > (It probably only matters on Windows which uses long =3D=3D int =3D 32= bit for > > strings longer than INT_MAX=2E) Done=2E The updated patch regtests fine=2E OK? Thanks, Harald Fortran - simplify length of substring with constant bounds gcc/fortran/ChangeLog: PR fortran/100950 * simplify=2Ec (substring_has_constant_len): New=2E (gfc_simplify_len): Handle case of substrings with constant bounds=2E gcc/testsuite/ChangeLog: PR fortran/100950 * gfortran=2Edg/pr100950=2Ef90: New test=2E --abmob-2a647071-03a6-4e3e-a0af-86f3e8b9000c Content-Type: text/x-patch Content-Disposition: attachment; filename=pr100950-v3.patch Content-Transfer-Encoding: quoted-printable diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index c27b47aa98f..8f7fcec94c8 100644 =2D-- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -4512,6 +4512,69 @@ gfc_simplify_leadz (gfc_expr *e) } +/* Check for constant length of a substring. */ + +static bool +substring_has_constant_len (gfc_expr *e) +{ + gfc_ref *ref; + HOST_WIDE_INT istart, iend, length; + bool equal_length =3D false; + + if (e->ts.type !=3D BT_CHARACTER || e->ts.deferred) + return false; + + for (ref =3D e->ref; ref; ref =3D ref->next) + if (ref->type !=3D REF_COMPONENT) + break; + + if (!ref + || ref->type !=3D REF_SUBSTRING + || !ref->u.ss.start + || ref->u.ss.start->expr_type !=3D EXPR_CONSTANT + || !ref->u.ss.end + || ref->u.ss.end->expr_type !=3D EXPR_CONSTANT + || !ref->u.ss.length + || !ref->u.ss.length->length + || ref->u.ss.length->length->expr_type !=3D EXPR_CONSTANT) + return false; + + /* Basic checks on substring starting and ending indices. */ + if (!gfc_resolve_substring (ref, &equal_length)) + return false; + + istart =3D gfc_mpz_get_hwi (ref->u.ss.start->value.integer); + iend =3D gfc_mpz_get_hwi (ref->u.ss.end->value.integer); + length =3D gfc_mpz_get_hwi (ref->u.ss.length->length->value.integer); + + if (istart <=3D iend) + { + if (istart < 1) + { + gfc_error ("Substring start index (" HOST_WIDE_INT_PRINT_DEC + ") at %L below 1", + istart, &ref->u.ss.start->where); + return false; + } + if (iend > length) + { + gfc_error ("Substring end index (" HOST_WIDE_INT_PRINT_DEC + ") at %L exceeds string length", + iend, &ref->u.ss.end->where); + return false; + } + length =3D iend - istart + 1; + } + else + length =3D 0; + + /* Fix substring length. */ + e->value.character.length =3D length; + + return true; +} + + gfc_expr * gfc_simplify_len (gfc_expr *e, gfc_expr *kind) { @@ -4521,7 +4584,11 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind) if (k =3D=3D -1) return &gfc_bad_expr; - if (e->expr_type =3D=3D EXPR_CONSTANT) + if (e->ts.deferred) + return NULL; + + if (e->expr_type =3D=3D EXPR_CONSTANT + || substring_has_constant_len (e)) { result =3D gfc_get_constant_expr (BT_INTEGER, k, &e->where); mpz_set_si (result->value.integer, e->value.character.length); diff --git a/gcc/testsuite/gfortran.dg/pr100950.f90 b/gcc/testsuite/gfortr= an.dg/pr100950.f90 new file mode 100644 index 00000000000..a86c8016e2e =2D-- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr100950.f90 @@ -0,0 +1,29 @@ +! { dg-do run } +! PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.= c:5514 + +program p + character(8), parameter :: u =3D "123" + character(8) :: x =3D "", s + character(2) :: w(2) =3D [character(len(x(3:4))) :: 'a','b' = ] + character(*), parameter :: y(*) =3D [character(len(u(3:4))) :: 'a','b' = ] + character(*), parameter :: z(*) =3D [character(len(x(3:4))) :: 'a','b' = ] + character(*), parameter :: t(*) =3D [character(len(x( :2))) :: 'a','b' = ] + character(*), parameter :: v(*) =3D [character(len(x(7: ))) :: 'a','b' = ] + type t_ + character(len=3D5) :: s + end type t_ + type(t_) :: q, r(1) + integer, parameter :: lq =3D len (q%s(3:4)), lr =3D len (r%s(3:4)) + + if (len (y) /=3D 2) stop 1 + if (len (z) /=3D 2) stop 2 + if (any (w /=3D y)) stop 3 + if (len ([character(len(u(3:4))) :: 'a','b' ]) /=3D 2) stop 4 + if (len ([character(len(x(3:4))) :: 'a','b' ]) /=3D 2) stop 5 + if (any ([character(len(x(3:4))) :: 'a','b' ] /=3D y)) stop 6 + write(s,*) [character(len(x(3:4))) :: 'a','b' ] + if (s /=3D " a b ") stop 7 + if (len (t) /=3D 2) stop 8 + if (len (v) /=3D 2) stop 9 + if (lq /=3D 2 .or. lr /=3D 2) stop 10 +end --abmob-2a647071-03a6-4e3e-a0af-86f3e8b9000c--