See attached 3 of 5 patch
Regression tested on x86_64
Regards,
Jerry
---
fortran: [PR49802]-3 Allow VALUE on assumed-shape and
explicit-shape array dummies
Fortran 2003 C527 prohibited the VALUE attribute on any array dummy.
Fortran 2008 relaxed this with C557, which prohibits only an
assumed-size array, a coarray, and an entity with a coarray ultimate
component. gfortran was rejecting the whole combination in
gfc_check_conflict, so the diagnostic for an assumed-rank dummy also
came out as a VALUE/DIMENSION conflict rather than naming the real
constraint.
resolve.cc takes over the check, gated by gfc_notify_std so that
-std=f2003 still rejects an array VALUE dummy. An assumed-size array
is rejected outright. So is an array VALUE dummy of a BIND(C)
procedure, since only a scalar VALUE dummy is interoperable with a
formal parameter of the C prototype (F2023, 18.3.6 (4)), and a
polymorphic array VALUE dummy, as not yet implemented.
trans-types.cc keeps the dummy passed by reference, and
gfc_conv_procedure_call gives it a private copy of the actual argument
through gfc_conv_subref_array_arg with INTENT_IN, so nothing is written
back. The copy is deep, so that a callee cannot reach the actual
argument's data through a shared allocatable component.
PR fortran/49802
gcc/fortran/ChangeLog:
* resolve.cc (resolve_symbol): Allow VALUE on assumed-shape and
explicit-shape array dummies under Fortran 2008 (C557); reject it
on assumed-size arrays, on array dummies of a BIND(C) procedure,
and, as not yet implemented, on polymorphic array dummies.
* symbol.cc (gfc_check_conflict): Remove the conflict between
VALUE and DIMENSION; only VALUE and CODIMENSION remain mutually
exclusive.
* trans-expr.cc (gfc_conv_procedure_call): For a VALUE array
dummy, pass a private deep copy of the actual argument via
gfc_conv_subref_array_arg with INTENT_IN.
* trans-types.cc (gfc_sym_type): Use byref=1 for VALUE array
dummies, so the ABI still passes by reference.
gcc/testsuite/ChangeLog:
* gfortran.dg/value_3.f90: Compile under -std=f2003 and replace the
now-invalid expectation that an explicit-shape array dummy with
VALUE conflicts with DIMENSION; this combination is permitted
(F2008, C557).
* gfortran.dg/assumed_rank_11.f90: Update expected diagnostic for
VALUE on an assumed-rank dummy.
* gfortran.dg/c-interop/c535a-2.f90: Likewise.
* gfortran.dg/value_12.f90: New test.
* gfortran.dg/value_13.f90: New test.
* gfortran.dg/value_16.f90: New test.
* gfortran.dg/value_17.f90: New test.
---From 4fb6f700d950f9144541d90bd13bd797ef941b30 Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Sun, 23 Aug 2026 18:29:33 -0700
Subject: [PATCH 3/5] fortran: [PR49802]-3 Allow VALUE on assumed-shape and
explicit-shape array dummies
Fortran 2003 C527 prohibited the VALUE attribute on any array dummy.
Fortran 2008 relaxed this with C557, which prohibits only an
assumed-size array, a coarray, and an entity with a coarray ultimate
component. gfortran was rejecting the whole combination in
gfc_check_conflict, so the diagnostic for an assumed-rank dummy also
came out as a VALUE/DIMENSION conflict rather than naming the real
constraint.
resolve.cc takes over the check, gated by gfc_notify_std so that
-std=f2003 still rejects an array VALUE dummy. An assumed-size array
is rejected outright. So is an array VALUE dummy of a BIND(C)
procedure, since only a scalar VALUE dummy is interoperable with a
formal parameter of the C prototype (F2023, 18.3.6 (4)), and a
polymorphic array VALUE dummy, as not yet implemented.
trans-types.cc keeps the dummy passed by reference, and
gfc_conv_procedure_call gives it a private copy of the actual argument
through gfc_conv_subref_array_arg with INTENT_IN, so nothing is written
back. The copy is deep, so that a callee cannot reach the actual
argument's data through a shared allocatable component.
PR fortran/49802
gcc/fortran/ChangeLog:
* resolve.cc (resolve_symbol): Allow VALUE on assumed-shape and
explicit-shape array dummies under Fortran 2008 (C557); reject it
on assumed-size arrays, on array dummies of a BIND(C) procedure,
and, as not yet implemented, on polymorphic array dummies.
* symbol.cc (gfc_check_conflict): Remove the conflict between
VALUE and DIMENSION; only VALUE and CODIMENSION remain mutually
exclusive.
* trans-expr.cc (gfc_conv_procedure_call): For a VALUE array
dummy, pass a private deep copy of the actual argument via
gfc_conv_subref_array_arg with INTENT_IN.
* trans-types.cc (gfc_sym_type): Use byref=1 for VALUE array
dummies, so the ABI still passes by reference.
gcc/testsuite/ChangeLog:
* gfortran.dg/value_3.f90: Compile under -std=f2003 and replace the
now-invalid expectation that an explicit-shape array dummy with
VALUE conflicts with DIMENSION; this combination is permitted
(F2008, C557).
* gfortran.dg/assumed_rank_11.f90: Update expected diagnostic for
VALUE on an assumed-rank dummy.
* gfortran.dg/c-interop/c535a-2.f90: Likewise.
* gfortran.dg/value_12.f90: New test.
* gfortran.dg/value_13.f90: New test.
* gfortran.dg/value_16.f90: New test.
* gfortran.dg/value_17.f90: New test.
---
gcc/fortran/resolve.cc | 36 ++++++++++
gcc/fortran/symbol.cc | 1 -
gcc/fortran/trans-expr.cc | 9 +++
gcc/fortran/trans-types.cc | 1 +
gcc/testsuite/gfortran.dg/assumed_rank_11.f90 | 8 +--
.../gfortran.dg/c-interop/c535a-2.f90 | 4 +-
gcc/testsuite/gfortran.dg/value_12.f90 | 69 +++++++++++++++++++
gcc/testsuite/gfortran.dg/value_13.f90 | 18 +++++
gcc/testsuite/gfortran.dg/value_16.f90 | 50 ++++++++++++++
gcc/testsuite/gfortran.dg/value_17.f90 | 28 ++++++++
gcc/testsuite/gfortran.dg/value_3.f90 | 12 +++-
11 files changed, 226 insertions(+), 10 deletions(-)
create mode 100644 gcc/testsuite/gfortran.dg/value_12.f90
create mode 100644 gcc/testsuite/gfortran.dg/value_13.f90
create mode 100644 gcc/testsuite/gfortran.dg/value_16.f90
create mode 100644 gcc/testsuite/gfortran.dg/value_17.f90
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index f1577f482b9..150cfe28b5d 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -18863,6 +18863,42 @@ skip_interfaces:
"CODIMENSION attribute", &sym->declared_at);
return;
}
+
+ /* F2008, C557 (F2018, C862; F2023, C867). Assumed-shape and
+ explicit-shape array dummies may have the VALUE attribute, but
+ assumed-size arrays may not. */
+ if (as->type == AS_ASSUMED_SIZE && sym->attr.value)
+ {
+ gfc_error ("Assumed-size array %qs at %L may not have the VALUE "
+ "attribute", sym->name, &sym->declared_at);
+ return;
+ }
+ else if (sym->attr.value && sym->attr.dummy
+ && (as->type == AS_EXPLICIT || as->type == AS_ASSUMED_SHAPE))
+ {
+ if (!gfc_notify_std (GFC_STD_F2008, "Array dummy argument %qs at "
+ "%L with VALUE attribute", sym->name,
+ &sym->declared_at))
+ return;
+
+ /* F2023, 18.3.6 (4): only a scalar VALUE dummy is interoperable
+ with a formal parameter of the C prototype. */
+ if (sym->ns->proc_name && sym->ns->proc_name->attr.is_bind_c)
+ {
+ gfc_error ("Array dummy argument %qs at %L with VALUE attribute "
+ "not allowed in BIND(C) procedure %qs", sym->name,
+ &sym->declared_at, sym->ns->proc_name->name);
+ return;
+ }
+
+ if (sym->ts.type == BT_CLASS)
+ {
+ gfc_error ("Sorry, polymorphic array dummy argument %qs at %L "
+ "with VALUE attribute is not yet implemented",
+ sym->name, &sym->declared_at);
+ return;
+ }
+ }
}
/* Make sure symbols with known intent or optional are really dummy
diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
index 57e3daa5767..74388144b0a 100644
--- a/gcc/fortran/symbol.cc
+++ b/gcc/fortran/symbol.cc
@@ -694,7 +694,6 @@ gfc_check_conflict (symbol_attribute *attr, const char *name, locus *where)
conf (value, subroutine)
conf (value, function)
conf (value, volatile_)
- conf (value, dimension)
conf (value, codimension)
conf (value, external)
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 1bc96864eeb..32972d9c84a 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -8109,6 +8109,15 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
/* Implement F2018, 18.3.6, list item (5), bullet point 2. */
gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
+ else if (fsym && fsym->attr.value && fsym->attr.dimension
+ && e->rank != -1)
+ /* VALUE array dummy: pass a private copy of the actual
+ argument. Allocatable components are copied deeply, so
+ that the callee cannot reach the actual argument's data. */
+ gfc_conv_subref_array_arg (&parmse, e, nodesc_arg, INTENT_IN,
+ false, fsym, sym->name, NULL,
+ false, true);
+
else if (e->expr_type == EXPR_VARIABLE
&& is_subref_array (e)
&& !(fsym && fsym->attr.pointer)
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index d9e6a12068e..04786b83746 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2523,6 +2523,7 @@ gfc_sym_type (gfc_symbol * sym, bool is_bind_c)
if (sym->attr.dummy && !sym->attr.function
&& (!sym->attr.value
+ || sym->attr.dimension
|| (sym->ts.type == BT_CHARACTER
&& (!sym->ts.u.cl || !sym->ts.u.cl->length
|| sym->ts.u.cl->length->expr_type != EXPR_CONSTANT)))
diff --git a/gcc/testsuite/gfortran.dg/assumed_rank_11.f90 b/gcc/testsuite/gfortran.dg/assumed_rank_11.f90
index 46dffd0740b..ed87ca73ee7 100644
--- a/gcc/testsuite/gfortran.dg/assumed_rank_11.f90
+++ b/gcc/testsuite/gfortran.dg/assumed_rank_11.f90
@@ -42,11 +42,11 @@ subroutine orig(X) ! { dg-error "may not have the VALUE or CODIMENSION attribute
integer :: x(..)[*]
end
-subroutine val1(X)
- integer, value :: x(..) ! { dg-error "VALUE attribute conflicts with DIMENSION attribute" }
+subroutine val1(X) ! { dg-error "may not have the VALUE or CODIMENSION attribute" }
+ integer, value :: x(..)
end
-subroutine val2(X)
+subroutine val2(X) ! { dg-error "may not have the VALUE or CODIMENSION attribute" }
integer, value :: x
- dimension :: x(..) ! { dg-error "VALUE attribute conflicts with DIMENSION attribute" }
+ dimension :: x(..)
end
diff --git a/gcc/testsuite/gfortran.dg/c-interop/c535a-2.f90 b/gcc/testsuite/gfortran.dg/c-interop/c535a-2.f90
index 816e69124ce..742c0f878a5 100644
--- a/gcc/testsuite/gfortran.dg/c-interop/c535a-2.f90
+++ b/gcc/testsuite/gfortran.dg/c-interop/c535a-2.f90
@@ -71,8 +71,8 @@ subroutine s2 (b) ! { dg-error "has no IMPLICIT type" }
integer, codimension[*] :: b(..) ! { dg-error "assumed-rank array" }
end subroutine
-subroutine s5 (e) ! { dg-error "has no IMPLICIT type" }
+subroutine s5 (e) ! { dg-error "may not have the VALUE or CODIMENSION attribute" }
implicit none
- integer, value :: e(..) ! { dg-error "VALUE attribute conflicts with DIMENSION" }
+ integer, value :: e(..)
end subroutine
diff --git a/gcc/testsuite/gfortran.dg/value_12.f90 b/gcc/testsuite/gfortran.dg/value_12.f90
new file mode 100644
index 00000000000..d9460fd01ce
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/value_12.f90
@@ -0,0 +1,69 @@
+! { dg-do run }
+! PR 49802
+! VALUE was rejected outright for array dummy arguments ("VALUE
+! attribute conflicts with DIMENSION attribute"), even though F2018
+! C862 only prohibits VALUE for assumed-size arrays (and coarrays).
+! Verify that assumed-shape, explicit-shape, and
+! non-contiguous array actuals are passed by VALUE correctly: the
+! callee gets a private copy, and modifications do not propagate back
+! to the actual argument, including for PARAMETER actuals.
+
+program test
+ implicit none
+ integer, parameter :: p(5) = [1,2,3,4,5]
+ character(len=*), parameter :: c1(2) = [ "abc", "def" ]
+ integer :: a(10), i
+
+ a = [(i, i=1,10)]
+
+ call sub_int_assumed_shape (p)
+ if (any (p /= [1,2,3,4,5])) stop 1
+
+ call sub_int_noncontig (a(1:10:2))
+ if (any (a /= [(i, i=1,10)])) stop 2
+
+ call sub_int_explicit (p)
+ if (any (p /= [1,2,3,4,5])) stop 3
+
+ call sub_opt_array (p)
+ call sub_opt_array ()
+
+ call sub_char_assumed_shape (c1)
+ if (c1(1) /= "abc") stop 4
+
+contains
+
+ subroutine sub_int_assumed_shape (x)
+ integer, value :: x(:)
+ x = x + 100
+ if (any (x /= [101,102,103,104,105])) stop 11
+ end subroutine
+
+ subroutine sub_int_noncontig (x)
+ integer, value :: x(:)
+ x = -1
+ if (any (x /= -1)) stop 12
+ end subroutine
+
+ subroutine sub_int_explicit (x)
+ integer, value :: x(5)
+ x(1) = -99
+ if (x(1) /= -99) stop 13
+ end subroutine
+
+ subroutine sub_opt_array (x)
+ integer, value, optional :: x(:)
+ if (present (x)) then
+ if (any (x /= [1,2,3,4,5])) stop 14
+ x = -1
+ end if
+ end subroutine
+
+ subroutine sub_char_assumed_shape (x)
+ character(len=*), value :: x(:)
+ if (len (x) /= 3) stop 15
+ x(1)(1:1) = "1"
+ if (x(1)(1:1) /= "1") stop 16
+ end subroutine
+
+end program test
diff --git a/gcc/testsuite/gfortran.dg/value_13.f90 b/gcc/testsuite/gfortran.dg/value_13.f90
new file mode 100644
index 00000000000..b6f525f4777
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/value_13.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-options "-std=f2008" }
+! PR 49802
+! Assumed-shape and explicit-shape array dummies may have the VALUE
+! attribute since Fortran 2008 (F2008, C557), but assumed-size arrays
+! may not.
+
+subroutine foo (x)
+ integer, value :: x(:) ! assumed-shape: OK
+end subroutine
+
+subroutine bar (x)
+ integer, value :: x(10) ! explicit-shape: OK
+end subroutine
+
+subroutine baz (x) ! { dg-error "may not have the VALUE attribute" }
+ integer, value :: x(*)
+end subroutine
diff --git a/gcc/testsuite/gfortran.dg/value_16.f90 b/gcc/testsuite/gfortran.dg/value_16.f90
new file mode 100644
index 00000000000..d9ba5999387
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/value_16.f90
@@ -0,0 +1,50 @@
+! { dg-do run }
+! PR 49802
+! A VALUE array dummy of a derived type with allocatable components was
+! given a shallow copy, so the callee reached the actual argument's data
+! through the shared component pointers. The copy must be deep.
+
+program test
+ implicit none
+ type :: inner
+ integer, allocatable :: d(:)
+ end type
+ type :: outer
+ type(inner), allocatable :: b(:)
+ character(:), allocatable :: nm
+ end type
+ type(outer) :: v(2)
+ integer :: k
+
+ do k = 1, 2
+ allocate (v(k)%b(2))
+ allocate (v(k)%b(1)%d(2), source=[k,k])
+ allocate (v(k)%b(2)%d(2), source=[10*k,10*k])
+ v(k)%nm = "orig"
+ end do
+
+ call explicit_shape (v)
+ if (any (v(1)%b(1)%d /= [1,1])) stop 1
+ if (v(1)%nm /= "orig") stop 2
+
+ call assumed_shape (v)
+ if (any (v(2)%b(2)%d /= [20,20])) stop 3
+ if (v(2)%nm /= "orig") stop 4
+
+contains
+
+ subroutine explicit_shape (x)
+ type(outer), value :: x(2)
+ x(1)%b(1)%d = [-1,-1]
+ x(1)%nm = "changed"
+ if (any (x(1)%b(1)%d /= [-1,-1])) stop 11
+ end subroutine
+
+ subroutine assumed_shape (x)
+ type(outer), value :: x(:)
+ x(2)%b(2)%d = [-9,-9]
+ x(2)%nm = "changed"
+ if (x(2)%nm /= "changed") stop 21
+ end subroutine
+
+end program
diff --git a/gcc/testsuite/gfortran.dg/value_17.f90 b/gcc/testsuite/gfortran.dg/value_17.f90
new file mode 100644
index 00000000000..9ca70e59eb4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/value_17.f90
@@ -0,0 +1,28 @@
+! { dg-do compile }
+! PR 49802
+! Only a scalar VALUE dummy is interoperable with a formal parameter of
+! the C prototype (F2023, 18.3.6 (4)), so an array VALUE dummy is not
+! allowed in a BIND(C) procedure. A polymorphic array VALUE dummy is
+! not yet implemented; it used to ICE.
+
+module m
+ use iso_c_binding
+ implicit none
+ type :: t
+ integer :: i = 0
+ end type
+contains
+
+ subroutine bindc_expl (x) bind(c) ! { dg-error "not allowed in BIND\\(C\\) procedure" }
+ integer(c_int), value :: x(3)
+ end subroutine
+
+ subroutine bindc_ashape (x) bind(c) ! { dg-error "not allowed in BIND\\(C\\) procedure" }
+ integer(c_int), value :: x(:)
+ end subroutine
+
+ subroutine poly (x) ! { dg-error "not yet implemented" }
+ class(t), value :: x(:)
+ end subroutine
+
+end module
diff --git a/gcc/testsuite/gfortran.dg/value_3.f90 b/gcc/testsuite/gfortran.dg/value_3.f90
index c5d2d1f27df..0a5308cb88e 100644
--- a/gcc/testsuite/gfortran.dg/value_3.f90
+++ b/gcc/testsuite/gfortran.dg/value_3.f90
@@ -1,8 +1,14 @@
! { dg-do compile }
+! { dg-options "-std=f2003" }
! Tests the constraints in the patch for PR29642, which requested the
! implementation of the F2003 VALUE attribute for gfortran.
!
-! Contributed by Paul Thomas <[email protected]>
+! Compiled as -std=f2003 because Fortran 2008 relaxed C527 to allow the
+! VALUE attribute on explicit-shape and assumed-shape array dummies
+! (F2008, C557); bar_1 below exercises the resulting -std=f2003
+! rejection. The acceptance case is covered separately by value_12.f90.
+!
+! Contributed by Paul Thomas <[email protected]>
!
program test_value
integer(8) :: i = 42, j ! { dg-error "not a dummy" }
@@ -10,10 +16,10 @@ program test_value
value :: j
contains
- subroutine bar_1 (i)
+ subroutine bar_1 (i) ! { dg-error "Fortran 2008: Array dummy argument" }
integer(8) :: i
dimension i(8)
- value :: i ! { dg-error "conflicts with DIMENSION" }
+ value :: i
i = 0
end subroutine bar_1
--
2.55.0