Re: [PATCH] Fortran: fix checking of MOLD= in ALLOCATE statements [PR51961]

2025-06-15 Thread Jerry D

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]

2025-06-15 Thread Steve Kargl
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]

2025-06-15 Thread Harald Anlauf

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]

2025-06-15 Thread 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=).

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]

2025-06-15 Thread Harald Anlauf

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