Dear all, when checking the SOURCE and SHAPE arguments to the RESHAPE intrinsic, for absent PAD argument we failed to handle the case when SHAPE was a parameter.
Fortunately, the proper check was already there, and the code just needs some tweaking, as well as one of the testcases. Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald
From d6af2a33bad852bcea39b8c5b2e7c27976bde2a1 Mon Sep 17 00:00:00 2001 From: Harald Anlauf <anl...@gmx.de> Date: Wed, 24 Nov 2021 22:22:24 +0100 Subject: [PATCH] Fortran: improve check of arguments to the RESHAPE intrinsic gcc/fortran/ChangeLog: PR fortran/103411 * check.c (gfc_check_reshape): Improve check of size of source array for the RESHAPE intrinsic against the given shape when pad is not given, and shape is a parameter. gcc/testsuite/ChangeLog: PR fortran/103411 * gfortran.dg/reshape_7.f90: Adjust test to improved check. * gfortran.dg/reshape_9.f90: New test. --- gcc/fortran/check.c | 17 +++++++++++++---- gcc/testsuite/gfortran.dg/reshape_7.f90 | 2 +- gcc/testsuite/gfortran.dg/reshape_9.f90 | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/reshape_9.f90 diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index 5a5aca10ebe..837eb0912c0 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -4699,6 +4699,7 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape, mpz_t size; mpz_t nelems; int shape_size; + bool shape_is_const = false; if (!array_check (source, 0)) return false; @@ -4736,6 +4737,7 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape, { gfc_expr *e; int i, extent; + shape_is_const = true; for (i = 0; i < shape_size; ++i) { e = gfc_constructor_lookup_expr (shape->value.constructor, i); @@ -4748,7 +4750,7 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape, gfc_error ("%qs argument of %qs intrinsic at %L has " "negative element (%d)", gfc_current_intrinsic_arg[1]->name, - gfc_current_intrinsic, &e->where, extent); + gfc_current_intrinsic, &shape->where, extent); return false; } } @@ -4766,6 +4768,7 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape, int i, extent; gfc_expr *e, *v; + shape_is_const = true; v = shape->symtree->n.sym->value; for (i = 0; i < shape_size; i++) @@ -4856,8 +4859,7 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape, } } - if (pad == NULL && shape->expr_type == EXPR_ARRAY - && gfc_is_constant_expr (shape) + if (pad == NULL && shape_is_const && !(source->expr_type == EXPR_VARIABLE && source->symtree->n.sym->as && source->symtree->n.sym->as->type == AS_ASSUMED_SIZE)) { @@ -4866,10 +4868,17 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape, { gfc_constructor *c; bool test; + gfc_constructor_base b; + if (shape->expr_type == EXPR_ARRAY) + b = shape->value.constructor; + else if (shape->expr_type == EXPR_VARIABLE) + b = shape->symtree->n.sym->value->value.constructor; + else + gcc_unreachable (); mpz_init_set_ui (size, 1); - for (c = gfc_constructor_first (shape->value.constructor); + for (c = gfc_constructor_first (b); c; c = gfc_constructor_next (c)) mpz_mul (size, size, c->expr->value.integer); diff --git a/gcc/testsuite/gfortran.dg/reshape_7.f90 b/gcc/testsuite/gfortran.dg/reshape_7.f90 index d752650aa4e..4216cb60cbb 100644 --- a/gcc/testsuite/gfortran.dg/reshape_7.f90 +++ b/gcc/testsuite/gfortran.dg/reshape_7.f90 @@ -4,7 +4,7 @@ subroutine p0 integer, parameter :: sh(2) = [2, 3] integer, parameter :: & - & a(2,2) = reshape([1, 2, 3, 4], sh) ! { dg-error "Different shape" } + & a(2,2) = reshape([1, 2, 3, 4], sh) ! { dg-error "not enough elements" } if (a(1,1) /= 0) STOP 1 end subroutine p0 diff --git a/gcc/testsuite/gfortran.dg/reshape_9.f90 b/gcc/testsuite/gfortran.dg/reshape_9.f90 new file mode 100644 index 00000000000..c46e211b47e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/reshape_9.f90 @@ -0,0 +1,14 @@ +! { dg-do compile } +! PR fortran/103411 - ICE in gfc_conv_array_initializer + +program p + integer, parameter :: a(2) = [2,2] + integer, parameter :: d(2,2) = reshape([1,2,3,4,5], a) + integer, parameter :: c(2,2) = reshape([1,2,3,4], a) + integer, parameter :: b(2,2) = & + reshape([1,2,3], a) ! { dg-error "not enough elements" } + print *, reshape([1,2,3], a) ! { dg-error "not enough elements" } + print *, reshape([1,2,3,4], a) + print *, reshape([1,2,3,4,5], a) + print *, b, c, d +end -- 2.26.2