Re: [PATCH] Fortran: fix checking of MOLD= in ALLOCATE statements [PR51961]
On 6/15/25 1:22 PM, Harald Anlauf wrote: Am 15.06.25 um 21:25 schrieb Harald Anlauf: Dear all, the attached patch fixes a rejects-valid: in an ALLOCATE statement with MOLD= present, if the allocate-object has an explicit-shape-spec, the compatibility of ranks is not required by the standard. (It is explicitly required only for SOURCE=). Oops, I attached the wrong patch. Fixed now... Since this could surprise users, we emit a warning if -Wsurprising is specified (contained in -Wall). This agrees with NAG's behavior. Testcase cross-checked with ifx and NAG. Regtested on x86_64-pc-linux-gnu. OK for mainline / 15-branch? Thanks, Harald Yes, looks OK Harald. Thanks. Jerry
Re: [PATCH, part1, v2] Fortran: various fixes for STAT/LSTAT/FSTAT intrinsics [PR82480]
Harald, I did a quick glance at the patch and did not see anything that jumped out as needing a change. OK to commit. Earlier today I came to the same conclusion that -1 on overflow is probably the right thing to do. Gfortran would need a way to supply the value of ERANGE (on all supported targets) so a user can write a test. Yes, POSIX seems to define ERANGE as 34, but is that guaranteed on non-POSIX targets? -- steve On Sun, Jun 15, 2025 at 09:01:37PM +0200, Harald Anlauf wrote: > > here's a modification that returns -1 for those components of stat > that would overflow assignment to integer(kind=4), and does not > return ERANGE as in v1 of this patch. There is no need to modify > the existing testcasese stat_{1,2}.f90. > > Cheers, > Harald > > Am 12.06.25 um 22:12 schrieb Harald Anlauf: > > Hi Steve, > > > > On 6/11/25 23:06, Steve Kargl wrote: > > > On Wed, Jun 11, 2025 at 10:18:37PM +0200, Harald Anlauf wrote: > > > > - for the INTEGER(KIND=4) versions the STATUS returns ERANGE if > > > > an overflow is encountered. > > > > > > > > The latter is certainly debatable, as one of the existing testcases > > > > stat_{1,2}.f90 may fail on systems where e.g. an inode number is larger > > > > than INT32_MAX may occur. Options are to drop the overflow check, or > > > > to run those testcases with additional option -fdefault-integer-8. > > > > > > > > Opinions? > > > > > > > > another option is: > > > > - return -1 for components which overflow, and not return ERANGE, > > thus to leave it up to the user to handle this > > > > It is arguably not an error generated by stat(3), but by the > > interface to Fortran in the runtime. > > > > > > > > Thanks for doing these types of cleanups. > > > > > > You may want to take a peek at > > > > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30372 > > > > > > where I posted a few cleanups for SLEEP, UMASK, UNLINK, > > > etc. In those cleanups, I would cast arguments to > > > integer(4) if I could (ie., if I know the arg was in range) > > > to prevent an explosion in the size of libgfortran. > > > > I do not plan to implement any new library versions. The > > *_i4 and *_i8 versions are already available. All integer > > arguments should be kind=4 or 8, and needed conversions > > can be done using scalar temporaries. > > > > > I'll need to think about your -fdefault-integer-8 question > > > for a bit. Because that option exists and can change > > > default integer kind, we'll need *_i4 and *_i8 versions of > > > the functions in libgfortran. I suspect we'll need to > > > run the testcases with -fdefault-integer-8. > > > > This depends on the way we handle overflow. The variant > > above would not need this option. > > > > > If no one approves your patch by Saturday, I'll review. > > > > Any helpful feedback is greatly appreciated. > > > > Thanks > > Harald > > > > > > > From aa79324885ba44b64911ec7a75375b28a2223cf7 Mon Sep 17 00:00:00 2001 > From: Harald Anlauf > Date: Sun, 15 Jun 2025 20:47:13 +0200 > Subject: [PATCH] Fortran: various fixes for STAT/LSTAT/FSTAT intrinsics > [PR82480] > > The GNU intrinsics STAT/LSTAT/FSTAT were inherited from g77, but changed > the names of some keywords: FILE became NAME, and SARRAY became VALUES, > which are the keywords documented in the gfortran manual. > Adjust code and libgfortran error messages to reflect this change. > Furthermore, add compile-time checking that INTENT(OUT) arguments are > definable, and that array VALUES has at least size 13. > > PR fortran/82480 > > gcc/fortran/ChangeLog: > > * check.cc (gfc_check_fstat): Extend checks to INTENT(OUT) arguments. > (gfc_check_fstat_sub): Likewise. > (gfc_check_stat): Likewise. > (gfc_check_stat_sub): Likewise. > > libgfortran/ChangeLog: > > * intrinsics/stat.c (stat_i4_sub_0): Fix argument names. Rename > SARRAY to VALUES also in error message. When array VALUES is > KIND=4, get only stat components that do not overflow INT32_MAX, > otherwise set the corresponding VALUES elements to -1. > (stat_i4_sub): Fix argument names. > (lstat_i4_sub): Likewise. > (stat_i8_sub_0): Likewise. > (stat_i8_sub): Likewise. > (lstat_i8_sub): Likewise. > (stat_i4): Likewise. > (stat_i8): Likewise. > (lstat_i4): Likewise. > (lstat_i8): Likewise. > (fstat_i4_sub): Likewise. > (fstat_i8_sub): Likewise. > (fstat_i4): Likewise. > (fstat_i8): Likewise. > > gcc/testsuite/ChangeLog: > > * gfortran.dg/stat_3.f90: New test. > --- > gcc/fortran/check.cc | 61 +++--- > gcc/testsuite/gfortran.dg/stat_3.f90 | 46 + > libgfortran/intrinsics/stat.c| 274 +++ > 3 files changed, 226 insertions(+), 155 deletions(-) > create mode 100644 gcc/testsuite/gfortran.dg/stat_3.f90 > > diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc > index c8904df3b21..838d523f7c4 10
[PATCH, part1, v2] Fortran: various fixes for STAT/LSTAT/FSTAT intrinsics [PR82480]
Dear all, here's a modification that returns -1 for those components of stat that would overflow assignment to integer(kind=4), and does not return ERANGE as in v1 of this patch. There is no need to modify the existing testcasese stat_{1,2}.f90. Cheers, Harald Am 12.06.25 um 22:12 schrieb Harald Anlauf: Hi Steve, On 6/11/25 23:06, Steve Kargl wrote: On Wed, Jun 11, 2025 at 10:18:37PM +0200, Harald Anlauf wrote: - for the INTEGER(KIND=4) versions the STATUS returns ERANGE if an overflow is encountered. The latter is certainly debatable, as one of the existing testcases stat_{1,2}.f90 may fail on systems where e.g. an inode number is larger than INT32_MAX may occur. Options are to drop the overflow check, or to run those testcases with additional option -fdefault-integer-8. Opinions? another option is: - return -1 for components which overflow, and not return ERANGE, thus to leave it up to the user to handle this It is arguably not an error generated by stat(3), but by the interface to Fortran in the runtime. Thanks for doing these types of cleanups. You may want to take a peek at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30372 where I posted a few cleanups for SLEEP, UMASK, UNLINK, etc. In those cleanups, I would cast arguments to integer(4) if I could (ie., if I know the arg was in range) to prevent an explosion in the size of libgfortran. I do not plan to implement any new library versions. The *_i4 and *_i8 versions are already available. All integer arguments should be kind=4 or 8, and needed conversions can be done using scalar temporaries. I'll need to think about your -fdefault-integer-8 question for a bit. Because that option exists and can change default integer kind, we'll need *_i4 and *_i8 versions of the functions in libgfortran. I suspect we'll need to run the testcases with -fdefault-integer-8. This depends on the way we handle overflow. The variant above would not need this option. If no one approves your patch by Saturday, I'll review. Any helpful feedback is greatly appreciated. Thanks Harald From aa79324885ba44b64911ec7a75375b28a2223cf7 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Sun, 15 Jun 2025 20:47:13 +0200 Subject: [PATCH] Fortran: various fixes for STAT/LSTAT/FSTAT intrinsics [PR82480] The GNU intrinsics STAT/LSTAT/FSTAT were inherited from g77, but changed the names of some keywords: FILE became NAME, and SARRAY became VALUES, which are the keywords documented in the gfortran manual. Adjust code and libgfortran error messages to reflect this change. Furthermore, add compile-time checking that INTENT(OUT) arguments are definable, and that array VALUES has at least size 13. PR fortran/82480 gcc/fortran/ChangeLog: * check.cc (gfc_check_fstat): Extend checks to INTENT(OUT) arguments. (gfc_check_fstat_sub): Likewise. (gfc_check_stat): Likewise. (gfc_check_stat_sub): Likewise. libgfortran/ChangeLog: * intrinsics/stat.c (stat_i4_sub_0): Fix argument names. Rename SARRAY to VALUES also in error message. When array VALUES is KIND=4, get only stat components that do not overflow INT32_MAX, otherwise set the corresponding VALUES elements to -1. (stat_i4_sub): Fix argument names. (lstat_i4_sub): Likewise. (stat_i8_sub_0): Likewise. (stat_i8_sub): Likewise. (lstat_i8_sub): Likewise. (stat_i4): Likewise. (stat_i8): Likewise. (lstat_i4): Likewise. (lstat_i8): Likewise. (fstat_i4_sub): Likewise. (fstat_i8_sub): Likewise. (fstat_i4): Likewise. (fstat_i8): Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/stat_3.f90: New test. --- gcc/fortran/check.cc | 61 +++--- gcc/testsuite/gfortran.dg/stat_3.f90 | 46 + libgfortran/intrinsics/stat.c| 274 +++ 3 files changed, 226 insertions(+), 155 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/stat_3.f90 diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc index c8904df3b21..838d523f7c4 100644 --- a/gcc/fortran/check.cc +++ b/gcc/fortran/check.cc @@ -6507,7 +6507,7 @@ gfc_check_fseek_sub (gfc_expr *unit, gfc_expr *offset, gfc_expr *whence, gfc_exp bool -gfc_check_fstat (gfc_expr *unit, gfc_expr *array) +gfc_check_fstat (gfc_expr *unit, gfc_expr *values) { if (!type_check (unit, 0, BT_INTEGER)) return false; @@ -6515,11 +6515,17 @@ gfc_check_fstat (gfc_expr *unit, gfc_expr *array) if (!scalar_check (unit, 0)) return false; - if (!type_check (array, 1, BT_INTEGER) + if (!type_check (values, 1, BT_INTEGER) || !kind_value_check (unit, 0, gfc_default_integer_kind)) return false; - if (!array_check (array, 1)) + if (!array_check (values, 1)) +return false; + + if (!variable_check (values, 1, false)) +return false; + + if (!array_size_check (values, 1, 13)) return false; return true; @@ -6527,19 +6533,9 @@ gfc_check_fstat (gfc_expr *unit, gfc_expr *array) bool -gfc_check_fstat_sub (gfc_expr *unit, gfc_expr *array, gfc_expr *status) +gfc_ch
[PATCH] Fortran: fix checking of MOLD= in ALLOCATE statements [PR51961]
Dear all, the attached patch fixes a rejects-valid: in an ALLOCATE statement with MOLD= present, if the allocate-object has an explicit-shape-spec, the compatibility of ranks is not required by the standard. (It is explicitly required only for SOURCE=). Since this could surprise users, we emit a warning if -Wsurprising is specified (contained in -Wall). This agrees with NAG's behavior. Testcase cross-checked with ifx and NAG. Regtested on x86_64-pc-linux-gnu. OK for mainline / 15-branch? Thanks, Harald diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index d09aef0a899..25d12768e97 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -8740,8 +8767,25 @@ static bool conformable_arrays (gfc_expr *e1, gfc_expr *e2) { gfc_ref *tail; + bool scalar; + for (tail = e2->ref; tail && tail->next; tail = tail->next); + /* If MOLD= is present and is not scalar, and the allocate-object has an + explicit-shape-spec, the ranks need not agree. Let's emit a warning if + -pedantic is given. */ + scalar = !tail || tail->type == REF_COMPONENT; + if (e1->mold && e1->rank > 0 + && (scalar || (tail->type == REF_ARRAY && tail->u.ar.type != AR_FULL))) +{ + if (scalar || (tail->u.ar.as && e1->rank != tail->u.ar.as->rank)) + gfc_warning (OPT_Wpedantic, "Allocate-object at %L has rank %d " + "but MOLD= expression at %L has rank %d", + &e2->where, scalar ? 0 : tail->u.ar.as->rank, + &e1->where, e1->rank); + return true; +} + /* First compare rank. */ if ((tail && (!tail->u.ar.as || e1->rank != tail->u.ar.as->rank)) || (!tail && e1->rank != e2->rank))
Re: [PATCH] Fortran: fix checking of MOLD= in ALLOCATE statements [PR51961]
Am 15.06.25 um 21:25 schrieb Harald Anlauf: Dear all, the attached patch fixes a rejects-valid: in an ALLOCATE statement with MOLD= present, if the allocate-object has an explicit-shape-spec, the compatibility of ranks is not required by the standard. (It is explicitly required only for SOURCE=). Oops, I attached the wrong patch. Fixed now... Since this could surprise users, we emit a warning if -Wsurprising is specified (contained in -Wall). This agrees with NAG's behavior. Testcase cross-checked with ifx and NAG. Regtested on x86_64-pc-linux-gnu. OK for mainline / 15-branch? Thanks, Harald Harald From 7194cdde73ed2b2c6ad6bc1a200a9f508c9659fa Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Sun, 15 Jun 2025 21:09:28 +0200 Subject: [PATCH] Fortran: fix checking of MOLD= in ALLOCATE statements [PR51961] In ALLOCATE statements where the MOLD= argument is present and is not scalar, and the allocate-object has an explicit-shape-spec, the standard does not require the ranks to agree. In that case we skip the rank check, but emit a warning if -Wsurprising is given. PR fortran/51961 gcc/fortran/ChangeLog: * resolve.cc (conformable_arrays): Use modified rank check when MOLD= expression is given. gcc/testsuite/ChangeLog: * gfortran.dg/allocate_with_mold_5.f90: New test. --- gcc/fortran/resolve.cc| 17 +++ .../gfortran.dg/allocate_with_mold_5.f90 | 51 +++ 2 files changed, 68 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/allocate_with_mold_5.f90 diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index d09aef0a899..5413d8f9c54 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -8740,8 +8740,25 @@ static bool conformable_arrays (gfc_expr *e1, gfc_expr *e2) { gfc_ref *tail; + bool scalar; + for (tail = e2->ref; tail && tail->next; tail = tail->next); + /* If MOLD= is present and is not scalar, and the allocate-object has an + explicit-shape-spec, the ranks need not agree. This may be unintended, + so let's emit a warning if -Wsurprising is given. */ + scalar = !tail || tail->type == REF_COMPONENT; + if (e1->mold && e1->rank > 0 + && (scalar || (tail->type == REF_ARRAY && tail->u.ar.type != AR_FULL))) +{ + if (scalar || (tail->u.ar.as && e1->rank != tail->u.ar.as->rank)) + gfc_warning (OPT_Wsurprising, "Allocate-object at %L has rank %d " + "but MOLD= expression at %L has rank %d", + &e2->where, scalar ? 0 : tail->u.ar.as->rank, + &e1->where, e1->rank); + return true; +} + /* First compare rank. */ if ((tail && (!tail->u.ar.as || e1->rank != tail->u.ar.as->rank)) || (!tail && e1->rank != e2->rank)) diff --git a/gcc/testsuite/gfortran.dg/allocate_with_mold_5.f90 b/gcc/testsuite/gfortran.dg/allocate_with_mold_5.f90 new file mode 100644 index 000..f5e2fc93d0a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/allocate_with_mold_5.f90 @@ -0,0 +1,51 @@ +! { dg-do compile } +! { dg-additional-options "-Wsurprising" } +! +! PR fortran/51961 - fix checking of MOLD= in ALLOCATE statements +! +! Contributed by Tobias Burnus + +program p + implicit none + type t + end type t + type u + class(t), allocatable :: a(:), b(:,:), c + end type u + class(T), allocatable :: a(:), b(:,:), c + type(u) :: z + + allocate (b(2,2)) + allocate (z% b(2,2)) + + allocate (a(2), mold=b(:,1)) + allocate (a(1:2),mold=b(1,:)) + allocate (a(2), mold=b)! { dg-warning "but MOLD= expression at" } + allocate (a(1:2),mold=b)! { dg-warning "but MOLD= expression at" } + allocate (z% a(2), mold=b(:,1)) + allocate (z% a(1:2), mold=b(1,:)) + allocate (z% a(2), mold=b)! { dg-warning "but MOLD= expression at" } + allocate (z% a(1:2), mold=b)! { dg-warning "but MOLD= expression at" } + allocate (z% a(2), mold=z% b(:,1)) + allocate (z% a(1:2), mold=z% b(1,:)) + allocate (z% a(2), mold=z% b) ! { dg-warning "but MOLD= expression at" } + allocate (z% a(1:2), mold=z% b) ! { dg-warning "but MOLD= expression at" } + + allocate (c, mold=b(1,1)) + allocate (c, mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% c, mold=b(1,1)) + allocate (z% c, mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% c, mold=z% b(1,1)) + allocate (z% c, mold=z% b)! { dg-warning "but MOLD= expression at" } + + allocate (a, mold=b(:,1)) + allocate (a, mold=b(1,:)) + allocate (z% a, mold=b(:,1)) + allocate (z% a, mold=b(1,:)) + allocate (z% a, mold=z% b(:,1)) + allocate (z% a, mold=z% b(1,:)) + + allocate (a, mold=b) ! { dg-error "or have the same rank" } + allocate (z% a, mold=b) ! { dg-error "or have the same rank" } + allocate (z% a, mold=z% b) ! { dg-error "or have the same rank" } +end -- 2.43.0