diff mbox series

PR fortran/97408 - Diagnose non-constant KIND argument to intrinsics

Message ID trinity-7e0ed16a-8136-41a0-809b-f25e340f5728-1602620223221@3c-app-gmx-bap55
State New
Headers show
Series PR fortran/97408 - Diagnose non-constant KIND argument to intrinsics | expand

Commit Message

Harald Anlauf Oct. 13, 2020, 8:17 p.m. UTC
While looking at some other PR, I found the urgent need for a rather
obvious improvement to compile-time diagnostics:
The KIND argument to intrinsics must be a compile-time constant.

Regtested on x86_64-pc-linux-gnu.

OK for master?

Thanks,
Harald


PR fortran/97408 - Diagnose non-constant KIND argument to intrinsics

The KIND argument to intrinsics must be a compile-time argument.
Improve check so that the proper diagnostics is emitted.

gcc/fortran/ChangeLog:

	* check.c (kind_check): Enhance check for non-constant KIND
	arguments.

gcc/testsuite/ChangeLog:

	* gfortran.dg/kind_2.f90: New test.

Comments

Tobias Burnus Oct. 13, 2020, 8:55 p.m. UTC | #1
On 10/13/20 10:17 PM, Harald Anlauf wrote:

> The KIND argument to intrinsics must be a compile-time argument.
> Improve check so that the proper diagnostics is emitted.
>
>
> -  if (!gfc_check_init_expr (k))
> +  if (!gfc_check_init_expr (k) || k->expr_type == EXPR_VARIABLE)

I think the real question is why is the following regarded as initialization expression:
       t = true;
…
       if (gfc_check_iter_variable (e))
         break;

Or worded differently: If
   integer, parameter :: A(*) = [(i, i=1,5)]
is valid, which should
   integer, parameter :: B(*) = [integer :: (int(i, kind=i), i=1,2)]
be invalid?

And, indeed, the Intel Fortran compiler does accept the code:
https://godbolt.org/z/EKbTf1
(While FLANG like gfortran does not.)

Thus, the first question should be whether that is valid code
according to the Fortran standard or not.

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter
Harald Anlauf Oct. 14, 2020, 6:25 p.m. UTC | #2
Hi Tobias,

> > The KIND argument to intrinsics must be a compile-time argument.
> > Improve check so that the proper diagnostics is emitted.
> >
> >
> > -  if (!gfc_check_init_expr (k))
> > +  if (!gfc_check_init_expr (k) || k->expr_type == EXPR_VARIABLE)
> 
> I think the real question is why is the following regarded as initialization expression:
>        t = true;
> …
>        if (gfc_check_iter_variable (e))
>          break;

you completely lost me here.  Did you accidentally delete some context?

> Or worded differently: If
>    integer, parameter :: A(*) = [(i, i=1,5)]
> is valid, which should
>    integer, parameter :: B(*) = [integer :: (int(i, kind=i), i=1,2)]
> be invalid?

Well, my copy of the F2018-FDIS says about the KIND argument to INT:

"KIND (optional) shall be a scalar integer constant expression."

Are you saying that (int(i, kind=i), i=1,2) is legal?
It would be helpful if you explained why "i" in kind=i is a constant expression.

> Thus, the first question should be whether that is valid code
> according to the Fortran standard or not.

Indeed.

Harald
Tobias Burnus Oct. 14, 2020, 6:42 p.m. UTC | #3
Hi Harald,

On 10/14/20 8:25 PM, Harald Anlauf wrote:
>> Or worded differently: If
>>     integer, parameter :: A(*) = [(i, i=1,5)]
>> is valid, which should
>>     integer, parameter :: B(*) = [integer :: (int(i, kind=i), i=1,2)]
>> be invalid?
> Well, my copy of the F2018-FDIS says about the KIND argument to INT:
> "KIND (optional) shall be a scalar integer constant expression."
Which applies to "B". For "A" (PARAMETER) it states: "entity has the
value specified byits constant-expr,"
> Are you saying that (int(i, kind=i), i=1,2) is legal?
> It would be helpful if you explained why "i" in kind=i is a constant expression.
I only say that it might be valid. – It would be likewise helpful if you
could explain why "i" is a const-expr in "[(i, i=1,5)]" – which we agree
is valid, don't we?. And what about "i" in "int(i)" for "[(kind(i),
i=1,5)]"?

I don't know whether it is valid – I just find it not obvious that [(i,
i=1,5)] is valid and [(int(1, kind=i), i=1,1)] is not.

Surely, if one first expands the array, it is valid: "[integer ::
(int(i, kind=i), i=1,2)]" → "[integer :: int(1, kind=1), int(2,kind=2)]"
→ "[integer :: 1_1, 2_2]" → "[1,2]".

In any case, gfc_check_init_expr is supposed to check for const-expr –
and if that does not work, gfc_check_init_expr should be fixed or at
least clearly understood when it can be used and when it cannot be used.

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter
diff mbox series

Patch

diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index 1e64fab3401..fa795538a7c 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -646,7 +646,7 @@  kind_check (gfc_expr *k, int n, bt type)
   if (!scalar_check (k, n))
     return false;

-  if (!gfc_check_init_expr (k))
+  if (!gfc_check_init_expr (k) || k->expr_type == EXPR_VARIABLE)
     {
       gfc_error ("%qs argument of %qs intrinsic at %L must be a constant",
 		 gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
diff --git a/gcc/testsuite/gfortran.dg/kind_2.f90 b/gcc/testsuite/gfortran.dg/kind_2.f90
new file mode 100644
index 00000000000..f3e5b7503ef
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/kind_2.f90
@@ -0,0 +1,12 @@ 
+! { dg-do compile }
+! PR97408 - Diagnose non-constant KIND argument to intrinsics
+
+program p
+  implicit none
+  integer :: i
+  integer, parameter :: lk(1) = [ 4 ]
+  print *, (int     (1     , lk(i)), i=1,1) ! { dg-error "must be a constant" }
+  print *, (real    (1     , lk(i)), i=1,1) ! { dg-error "must be a constant" }
+  print *, (cmplx   (1, kind=lk(i)), i=1,1) ! { dg-error "must be a constant" }
+  print *, (logical (.true., lk(i)), i=1,1) ! { dg-error "must be a constant" }
+end