The second patch attached.

I do need to adjust the commit message before final push.

Regardless, I wanted to get this out for review.

Also regression tested on x86_64.

OK for mainline?

Regards,

Jerry

---

Assisted by: Claude Sonnet 4.6

gcc/fortran/ChangeLog:

        * resolve.cc (resolve_symbol): Reject the VALUE attribute on
        assumed-size array dummies (F2018, C862); assumed-shape and
        explicit-shape array dummies are permitted.
        * symbol.cc (gfc_check_conflict): Remove the blanket 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 copy of the actual argument via
        gfc_conv_subref_array_arg with INTENT_IN, giving copy-in-only
        semantics with no write-back to the actual.
        * trans-types.cc (gfc_sym_type): Always pass array dummies by
        reference (descriptor), even when they have the VALUE
        attribute, since "VALUE for arrays" means copy-in data
        semantics rather than pass-by-value of the descriptor itself.

gcc/testsuite/ChangeLog:

        * 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_3.f90: Remove now-invalid expectation that
        an explicit-shape array dummy with VALUE conflicts with
        DIMENSION; this combination is permitted (F2018, C862).
        * gfortran.dg/pr49802_3.f90: New test.
        * gfortran.dg/pr49802_4.f90: New test.
---
From 2c43df3d21da1d885c908e4bd6e425726cb6e152 Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Fri, 12 Jun 2026 18:44:59 -0700
Subject: [PATCH] 	PR fortran/49802

gcc/fortran/ChangeLog:

	* resolve.cc (resolve_symbol): Reject the VALUE attribute on
	assumed-size array dummies (F2018, C862); assumed-shape and
	explicit-shape array dummies are permitted.
	* symbol.cc (gfc_check_conflict): Remove the blanket 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 copy of the actual argument via
	gfc_conv_subref_array_arg with INTENT_IN, giving copy-in-only
	semantics with no write-back to the actual.
	* trans-types.cc (gfc_sym_type): Always pass array dummies by
	reference (descriptor), even when they have the VALUE
	attribute, since "VALUE for arrays" means copy-in data
	semantics rather than pass-by-value of the descriptor itself.

gcc/testsuite/ChangeLog:

	* 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_3.f90: Remove now-invalid expectation that
	an explicit-shape array dummy with VALUE conflicts with
	DIMENSION; this combination is permitted (F2018, C862).
	* gfortran.dg/pr49802_3.f90: New test.
	* gfortran.dg/pr49802_4.f90: New test.
---
 gcc/fortran/resolve.cc                        |  9 +++
 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/pr49802_3.f90       | 69 +++++++++++++++++++
 gcc/testsuite/gfortran.dg/pr49802_4.f90       | 16 +++++
 gcc/testsuite/gfortran.dg/value_3.f90         |  2 +-
 9 files changed, 111 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/pr49802_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/pr49802_4.f90

diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index dffa0501858..6a8b2c64956 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -18734,6 +18734,15 @@ skip_interfaces:
 		     "CODIMENSION attribute", &sym->declared_at);
 	  return;
 	}
+
+      /* F2018, C862.  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;
+	}
     }
 
   /* Make sure symbols with known intent or optional are really dummy
diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
index 5a224be9884..f168b4a1ce1 100644
--- a/gcc/fortran/symbol.cc
+++ b/gcc/fortran/symbol.cc
@@ -689,7 +689,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 a8c5f34cbf1..973fe90bdcd 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -8040,6 +8040,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's data, with no copy-back, so that the callee
+		   cannot affect the actual through the dummy.  */
+		gfc_conv_subref_array_arg (&parmse, e, nodesc_arg, INTENT_IN,
+					    false, fsym, sym->name, sym,
+					    false);
+
 	      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 1c35e114db9..3df9616f2ee 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2518,6 +2518,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->attr.codimension
 	  || (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/pr49802_3.f90 b/gcc/testsuite/gfortran.dg/pr49802_3.f90
new file mode 100644
index 00000000000..89cd1cbdf8c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr49802_3.f90
@@ -0,0 +1,69 @@
+! { dg-do run }
+! PR fortran/49802
+! Follow-up: 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/pr49802_4.f90 b/gcc/testsuite/gfortran.dg/pr49802_4.f90
new file mode 100644
index 00000000000..7230956c184
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr49802_4.f90
@@ -0,0 +1,16 @@
+! { dg-do compile }
+! PR fortran/49802
+! Follow-up: assumed-shape and explicit-shape array dummies may have
+! the VALUE attribute (F2018 C862), 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_3.f90 b/gcc/testsuite/gfortran.dg/value_3.f90
index c5d2d1f27df..e05109503ea 100644
--- a/gcc/testsuite/gfortran.dg/value_3.f90
+++ b/gcc/testsuite/gfortran.dg/value_3.f90
@@ -13,7 +13,7 @@ contains
   subroutine bar_1 (i)
     integer(8) :: i
     dimension i(8)
-    value :: i  ! { dg-error "conflicts with DIMENSION" }
+    value :: i  ! Explicit-shape array dummy with VALUE is permitted (F2018, C862)
     i = 0
   end subroutine bar_1
 
-- 
2.54.0

Reply via email to