PR Fortran/91960 Patch

Message ID aWQJHTYZPir6fkzp@troutmask.apl.washington.edu
State New
Headers
Series PR Fortran/91960 Patch |

Commit Message

Steve Kargl Jan. 11, 2026, 8:33 p.m. UTC
  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

Jerry D Jan. 12, 2026, 5:48 p.m. UTC | #1
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
  
Steve Kargl Jan. 12, 2026, 8:04 p.m. UTC | #2
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
  
Jerry D Jan. 12, 2026, 9:54 p.m. UTC | #3
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
  

Patch

diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 2e8ce074c24..8584153c068 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -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;
 }
 
diff --git a/gcc/testsuite/gfortran.dg/pr69962.f90 b/gcc/testsuite/gfortran.dg/pr69962.f90
index 2684398ee31..30aaedfdf98 100644
--- a/gcc/testsuite/gfortran.dg/pr69962.f90
+++ b/gcc/testsuite/gfortran.dg/pr69962.f90
@@ -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" }
diff --git a/gcc/testsuite/gfortran.dg/pr91960_1.f90 b/gcc/testsuite/gfortran.dg/pr91960_1.f90
new file mode 100644
index 00000000000..90abcaf6934
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr91960_1.f90
@@ -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
diff --git a/gcc/testsuite/gfortran.dg/pr91960_2.f90 b/gcc/testsuite/gfortran.dg/pr91960_2.f90
new file mode 100644
index 00000000000..a7d41d9c417
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr91960_2.f90
@@ -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