Commit Message
The attach patch fixes PR Fortran/91960. This PR is another
one from Gerhard in 2019-10.01. A patch has been lingering
in the PR since 2023-05-30.
The patch checks that an array constructor in a parameter
statement is in fact a constant expression. I'll note
that the patch requires a special carve out to accommodate
the fix for Fortran/117070.
2026-01-11 Steven G. Kargl <kargl@gcc.gnu.org>
PR Fortran/91960
* resolve.cc (resolve_fl_parameter): Check the righthand symbol
is a constant expression.
2026-01-11 Steven G. Kargl <kargl@gcc.gnu.org>
PR Fortran/91960
* gfortran.dg/pr69962.f90: Adjust testcase to ignore new error message.
* gfortran.dg/pr91960_1.f90: New test.
* gfortran.dg/pr91960_2.f90: Ditto.
Comments
On 1/11/26 12:33 PM, Steve Kargl wrote:
> The attach patch fixes PR Fortran/91960. This PR is another
> one from Gerhard in 2019-10.01. A patch has been lingering
> in the PR since 2023-05-30.
>
> The patch checks that an array constructor in a parameter
> statement is in fact a constant expression. I'll note
> that the patch requires a special carve out to accommodate
> the fix for Fortran/117070.
>
> 2026-01-11 Steven G. Kargl <kargl@gcc.gnu.org>
>
> PR Fortran/91960
> * resolve.cc (resolve_fl_parameter): Check the righthand symbol
> is a constant expression.
>
> 2026-01-11 Steven G. Kargl <kargl@gcc.gnu.org>
>
> PR Fortran/91960
> * gfortran.dg/pr69962.f90: Adjust testcase to ignore new error message.
> * gfortran.dg/pr91960_1.f90: New test.
> * gfortran.dg/pr91960_2.f90: Ditto.
>
I am wondering about the comment:
+ /* PR fortran/117070 argues a nonconstant proc pointer can appear in
+ the array constructor of a paramater. I don't buy it, but... */
+ if (sym->value->ts.type == BT_DERIVED
+ && sym->value->ts.u.derived
+ && sym->value->ts.u.derived->attr.proc_pointer_comp)
+ return true;
+ gfc_error ("Expecting constant expression near %L", &sym->value->where);
+ return false;
It either is allowed or it is not. Do we need to review the Standard to confirm
or deny this?
Jerry
On Mon, Jan 12, 2026 at 09:48:56AM -0800, Jerry D wrote:
> On 1/11/26 12:33 PM, Steve Kargl wrote:
> > The attach patch fixes PR Fortran/91960. This PR is another
> > one from Gerhard in 2019-10.01. A patch has been lingering
> > in the PR since 2023-05-30.
> >
> > The patch checks that an array constructor in a parameter
> > statement is in fact a constant expression. I'll note
> > that the patch requires a special carve out to accommodate
> > the fix for Fortran/117070.
> >
> > 2026-01-11 Steven G. Kargl <kargl@gcc.gnu.org>
> >
> > PR Fortran/91960
> > * resolve.cc (resolve_fl_parameter): Check the righthand symbol
> > is a constant expression.
> >
> > 2026-01-11 Steven G. Kargl <kargl@gcc.gnu.org>
> >
> > PR Fortran/91960
> > * gfortran.dg/pr69962.f90: Adjust testcase to ignore new error message.
> > * gfortran.dg/pr91960_1.f90: New test.
> > * gfortran.dg/pr91960_2.f90: Ditto.
> >
>
> I am wondering about the comment:
>
> + /* PR fortran/117070 argues a nonconstant proc pointer can appear in
> + the array constructor of a paramater. I don't buy it, but... */
> + if (sym->value->ts.type == BT_DERIVED
> + && sym->value->ts.u.derived
> + && sym->value->ts.u.derived->attr.proc_pointer_comp)
> + return true;
> + gfc_error ("Expecting constant expression near %L", &sym->value->where);
> + return false;
>
> It either is allowed or it is not. Do we need to review the Standard to
> confirm or deny this?
>
It's probably easier to go see the audit in fortran/117070.
Here's a chopped down version of that PR.
module funcs
implicit none
abstract interface
function retchar()
character(len=1) :: retchar
end function
end interface
contains
function a()
character(len=1) :: a
a = 'a'
end function
end module
module dispatch_table
use funcs
implicit none
private
public :: table
public :: build_table, pc
! Procedure container
type :: pc
procedure(retchar), pointer, nopass :: rc => null()
end type
! Static dispatch table
type(pc), parameter :: table(3) = [pc(a)] ! Doesn't work
end module
The fix for 117070 accepts the line marked '! Doesn't work'.
The argument in that PR is that pc(a) is a constant expression.
I don't see how the address of function can be considered a
constant expression; in particular, some OS's support address
relocation and randomization.
--
Steve
On 1/12/26 12:04 PM, Steve Kargl wrote:
> On Mon, Jan 12, 2026 at 09:48:56AM -0800, Jerry D wrote:
>> On 1/11/26 12:33 PM, Steve Kargl wrote:
>>> The attach patch fixes PR Fortran/91960. This PR is another
>>> one from Gerhard in 2019-10.01. A patch has been lingering
>>> in the PR since 2023-05-30.
>>>
>>> The patch checks that an array constructor in a parameter
>>> statement is in fact a constant expression. I'll note
>>> that the patch requires a special carve out to accommodate
>>> the fix for Fortran/117070.
>>>
>>> 2026-01-11 Steven G. Kargl <kargl@gcc.gnu.org>
>>>
>>> PR Fortran/91960
>>> * resolve.cc (resolve_fl_parameter): Check the righthand symbol
>>> is a constant expression.
>>>
>>> 2026-01-11 Steven G. Kargl <kargl@gcc.gnu.org>
>>>
>>> PR Fortran/91960
>>> * gfortran.dg/pr69962.f90: Adjust testcase to ignore new error message.
>>> * gfortran.dg/pr91960_1.f90: New test.
>>> * gfortran.dg/pr91960_2.f90: Ditto.
>>>
>>
>> I am wondering about the comment:
>>
>> + /* PR fortran/117070 argues a nonconstant proc pointer can appear in
>> + the array constructor of a paramater. I don't buy it, but... */
>> + if (sym->value->ts.type == BT_DERIVED
>> + && sym->value->ts.u.derived
>> + && sym->value->ts.u.derived->attr.proc_pointer_comp)
>> + return true;
>> + gfc_error ("Expecting constant expression near %L", &sym->value->where);
>> + return false;
>>
>> It either is allowed or it is not. Do we need to review the Standard to
>> confirm or deny this?
>>
>
>
> It's probably easier to go see the audit in fortran/117070.
> Here's a chopped down version of that PR.
>
>
> module funcs
> implicit none
> abstract interface
> function retchar()
> character(len=1) :: retchar
> end function
> end interface
> contains
> function a()
> character(len=1) :: a
> a = 'a'
> end function
> end module
>
> module dispatch_table
> use funcs
> implicit none
> private
> public :: table
> public :: build_table, pc
>
> ! Procedure container
> type :: pc
> procedure(retchar), pointer, nopass :: rc => null()
> end type
>
> ! Static dispatch table
> type(pc), parameter :: table(3) = [pc(a)] ! Doesn't work
> end module
>
> The fix for 117070 accepts the line marked '! Doesn't work'.
> The argument in that PR is that pc(a) is a constant expression.
> I don't see how the address of function can be considered a
> constant expression; in particular, some OS's support address
> relocation and randomization.
>
> --
> Steve
I tested all of your test cases here with flang and it agrees with your error
messages. Simalarly with you chopped down test case here. I also tested the
proc_target_1.f90 with flang and it does not object. So at least one other
compiler lines up with gfortran with your patch applied.
It does seem inconsistent so I want to revise the comment as:
/* PR fortran/117070 argues a nonconstant proc pointer can appear in
the array constructor of a paramater. This seems inconsistant with
the concept of a parameter. TODO: Needs an interpretation. */
and plan to commit shortly.
Regards,
Jerry
@@ -17871,6 +17871,26 @@ resolve_fl_parameter (gfc_symbol *sym)
return false;
}
+ /* Some programmers can have a typo when using an implied-do loop to
+ initialize an array constant. For example,
+ INTEGER I,J
+ INTEGER, PARAMETER :: A(3) = [(I, I = 1, 3)] ! OK
+ INTEGER, PARAMETER :: B(3) = [(A(J), I = 1, 3)] ! Not OK, J undefined
+ This check catches the typo. */
+ if (sym->attr.dimension
+ && sym->value && sym->value->expr_type == EXPR_ARRAY
+ && !gfc_is_constant_expr (sym->value))
+ {
+ /* PR fortran/117070 argues a nonconstant proc pointer can appear in
+ the array constructor of a paramater. I don't buy it, but... */
+ if (sym->value->ts.type == BT_DERIVED
+ && sym->value->ts.u.derived
+ && sym->value->ts.u.derived->attr.proc_pointer_comp)
+ return true;
+ gfc_error ("Expecting constant expression near %L", &sym->value->where);
+ return false;
+ }
+
return true;
}
@@ -4,3 +4,4 @@ program p
character(3), parameter :: x(2) = ['abc', 'xyz']
character(2), parameter :: y(2) = [x(2)(2:3), x(n)(1:2)] ! { dg-error "CHARACTER length must be a constant" }
end
+! { dg-prune-output "Expecting constant expression" }
new file mode 100644
@@ -0,0 +1,6 @@
+! { dg-do compile }
+module m
+ integer :: i, j
+ integer, parameter :: a(3) = [1, 2, 3]
+ integer, parameter :: b(3) = [(a(j), i=1,3)] ! { dg-error "Expecting constant expression" }
+end
new file mode 100644
@@ -0,0 +1,8 @@
+! { dg-do compile }
+module m
+ implicit none
+ integer :: i, j
+ integer, parameter :: a(3) = [1, 2, 3]
+ integer, parameter :: c = a(j)
+ integer :: d = c ! { dg-error "initialization expression at" }
+end