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