Hi Jerry,
I did not have time for a thorough review, but here are some comments:
- thanks a lot for working on this! This actually addresses multiple
PRs: 49802, 102369, 104585, 110290.
- the following invalid code is only partially detected:
! These are invalid:
subroutine sub9_bind (x, y) bind(c) ! invalid, detected
character(1), intent(in) :: x(:)
character(1), value :: y(:)
end subroutine sub9_bind
subroutine sub10_bind (x, y, n) bind(c) ! invalid, NOT detected
integer, value :: n
character(1), intent(in) :: x(n)
character(1), value :: y(n)
end subroutine sub10_bind
subroutine sub11_bind (x, y, n) bind(c) ! invalid, NOT detected
integer, value, intent(in) :: n
character(1), intent(in) :: x(*)
character(1), value :: y(*)
end subroutine sub11_bind
See F2018:18.3.6 for details.
--- 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)))
I don't understand the || sym->attr.codimension part. I thought it
is not allowed to have coarray dummies with VALUE attribute per C863.
BTW:
+
+ /* F2018, C862. Assumed-shape and explicit-shape array dummies may
+ have the VALUE attribute, but assumed-size arrays may not. */
It is actually C863.
For previously existing testcases: please add -std=f2003 to allow
testing the old behavior before the change. This applies to
gfortran.dg/c-interop/c535a-2.f90
gfortran.dg/value_3.f90
Furthermore, consider changing the names of the new tests from
pr49802*.f90 to something like value*.f90. You do not fix a bug,
but update the compiler to a more modern standard. People who do
partial regression testing during development may appreciate it.
Thanks,
Harald
Am 13.06.26 um 10:27 PM schrieb Jerry D:
This bug has been around a long time. The attached is the first of two
patches.
Several test cases added. Some modified where restrictions changed.
Regression tested on x86_64.
OK for mainline?
Regards,
Jerry
---
Fortran: allow character(len=*), value dummy [PR49802]
Fortran 2003 C558 prohibited assumed-length character dummies with
VALUE, but Fortran 2008 removed that restriction. gfortran was still
rejecting it, and also rejected character dummies with VALUE whose
length is a non-constant specified-length expression (e.g. another
dummy argument). This patch has three parts:
resolve.cc: Relax the constraint to allow character(len=*) with VALUE,
using gfc_notify_std(GFC_STD_F2008) so -std=f2003 still rejects it.
The same Fortran 2008 allowance is extended to character dummies with
VALUE and a specified but non-constant length. The C-interop checks
are consolidated into a single "must have length one" condition (which
also covers, and rejects, the assumed-length and non-constant-length
cases since C has no equivalent), checked ahead of the Fortran 2008
allowance so C-interop dummies always get the same diagnostic.
trans-types.cc (gfc_sym_type): Assumed-length and non-constant-length
VALUE character dummies now use byref=1, giving them a pointer-based
ABI consistent with the callee's VLA parameter passing. Without this,
the callee compiled as a pointer-receiving function while the caller
packed bytes by value into registers, causing an ABI mismatch.
trans-expr.cc (conv_dummy_value): For assumed-length or non-constant-
length CHARACTER VALUE dummies, generate a caller-side copy (VLA alloca
+ memcpy) and pass its address, so the callee operates on the copy and
VALUE semantics are preserved. This lives in conv_dummy_value, the
common dummy-value conversion routine, rather than only in
gfc_conv_procedure_call's argument-walking loop, so the copy is made on
every path that converts a VALUE character dummy, not just direct
procedure-call arguments.
Assisted by: Claude Sonnet 4.6
PR fortran/49802
gcc/fortran/ChangeLog:
* resolve.cc: Allow character(len=*) VALUE from Fortran 2008,
and likewise a specified but non-constant length; use
gfc_notify_std for F2003 compatibility, and consolidate the
C-interop length checks into a single "must have length one"
check (covering assumed and non-constant length too) ordered
ahead of the Fortran 2008 allowance.
* trans-expr.cc (conv_dummy_value): For assumed-length or
non-constant-length CHARACTER VALUE dummies, make a caller-side
copy via DECL_EXPR alloca and gfc_build_memcpy_call, then pass
its address.
* trans-types.cc (gfc_sym_type): Use byref=1 for assumed-length
or non-constant-length VALUE character dummies so the ABI uses
pointer passing.
gcc/testsuite/ChangeLog:
* gfortran.dg/value_5.f90: Compile under -std=f2003 so the
Fortran 2008 assumed-length VALUE relaxation is exercised as a
rejection (foo4), and update the C-interop bar4 error
expectation to match the consolidated diagnostic; the F2008
acceptance case is covered separately by pr49802.f90 and
pr49802_1.f90.
* gfortran.dg/pr49802.f90: New test - run test for correctness
with assumed-length VALUE character dummies.
* gfortran.dg/pr49802_1.f90: New test - compile/error test for
-std=f2003 rejection.
* gfortran.dg/pr49802_2.f90: New test - run test for correctness
with a non-constant specified-length VALUE character dummy.
---