[PATCH 2 of 2] Fortran: allow character(len=*), value dummy [PR49802]
Jerry D <[email protected]> Sat, 13 Jun 2026 13:32:05 -0700
| Newsgroups | gmane.comp.gcc.patches,gmane.comp.gcc.fortran |
|---|---|
| Message-ID | <[email protected]> |
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. ---
PR49802-2of2-value-array-dummy.patch
(text/x-patch, 9.2 KB)
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