Fortran - improve checking for intrinsics allowed in constant expressions

gcc/fortran/ChangeLog:

	PR fortran/102458
	* expr.c (is_non_constant_intrinsic): Check for intrinsics
	excluded in constant expressions (F2018:10.1.2).
	(gfc_is_constant_expr): Use that check.

gcc/testsuite/ChangeLog:

	PR fortran/102458
	* gfortran.dg/pr102458.f90: New test.
This commit is contained in:
Harald Anlauf 2021-09-24 19:10:15 +02:00
parent 2364250ecc
commit 84cccff60a
2 changed files with 74 additions and 0 deletions

View File

@ -990,6 +990,34 @@ done:
}
/* Standard intrinsics listed under F2018:10.1.2 (6), which are excluded in
constant expressions, except TRANSFER (c.f. item (8)), which would need
separate treatment. */
static bool
is_non_constant_intrinsic (gfc_expr *e)
{
if (e->expr_type == EXPR_FUNCTION
&& e->value.function.isym)
{
switch (e->value.function.isym->id)
{
case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
case GFC_ISYM_GET_TEAM:
case GFC_ISYM_NULL:
case GFC_ISYM_NUM_IMAGES:
case GFC_ISYM_TEAM_NUMBER:
case GFC_ISYM_THIS_IMAGE:
return true;
default:
return false;
}
}
return false;
}
/* Determine if an expression is constant in the sense of F08:7.1.12.
* This function expects that the expression has already been simplified. */
@ -1023,6 +1051,10 @@ gfc_is_constant_expr (gfc_expr *e)
gcc_assert (e->symtree || e->value.function.esym
|| e->value.function.isym);
/* Check for intrinsics excluded in constant expressions. */
if (e->value.function.isym && is_non_constant_intrinsic (e))
return false;
/* Call to intrinsic with at least one argument. */
if (e->value.function.isym && e->value.function.actual)
{

View File

@ -0,0 +1,42 @@
! { dg-do compile }
! { dg-options "-fcoarray=lib" }
! PR fortran/102458 - standard intrinsics excluded in constant expressions
subroutine s1
integer :: a(command_argument_count()) = 1 ! { dg-error "Automatic array" }
print *, a
end
program p
block
integer :: a(get_team()) = 1 ! { dg-error "Automatic array" }
print *, a
end block
end
subroutine s2
integer :: a(num_images()) = 1 ! { dg-error "Automatic array" }
print *, a
end
function f()
block
integer :: a(team_number()) = 0 ! { dg-error "Automatic array" }
a = 1
end block
end
subroutine s3
integer :: a(this_image()) = 1 ! { dg-error "Automatic array" }
print *, a
end
subroutine s4
integer, parameter :: n = 4
integer, parameter :: x(transfer(n, n)) = 1 ! legal
integer :: y(transfer(n, n)) = 2 ! legal
integer, parameter :: k = size (x) ! ok
! integer, parameter :: m = size (y) ! fails, tracked separately
print *, k, x, y
if (k /= size (y)) stop 1
end