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

Reply via email to