Rev. 269177 uncovered a latent issue in TRANSFER when the MOLD argument had storage size 0, resulting in an infinite loop. The attached patch rejects illegal cases and handles the case where storage size of both SOURCE and MOLD are 0. It also verifies proper simplification for some cases, some of which were not always properly handled before.
Thanks to Dominique for the heads-up which I initially missed. Regtested on x86_64-pc-linux-gnu; the testcase is based on the report and slightly extended. OK for trunk? Thanks, and sorry for any inconvenience caused, Harald 2019-02-25 Harald Anlauf <anl...@gmx.de> PR fortran/89492 * check.c (gfc_calculate_transfer_sizes): Handle cases where storage size of elements of MOLD is 0. 2019-02-25 Harald Anlauf <anl...@gmx.de> PR fortran/89492 * gfortran.dg/pr89492.f90: New test.
Index: gcc/fortran/check.c =================================================================== --- gcc/fortran/check.c (revision 269177) +++ gcc/fortran/check.c (working copy) @@ -5487,6 +5487,26 @@ if (!gfc_element_size (mold, &result_elt_size)) return false; + if (result_elt_size == 0 && *source_size > 0) + { + gfc_error ("%<MOLD%> argument of %<TRANSFER%> intrinsic at %L " + "shall not have storage size 0 when %<SOURCE%> " + "argument has size greater than 0", &mold->where); + return false; + } + + /* If MOLD is a scalar and SIZE is absent, the result is a scalar. + * If MOLD is an array and SIZE is absent, the result is an array and of + * rank one. Its size is as small as possible such that its physical + * representation is not shorter than that of SOURCE. + */ + if (result_elt_size == 0 && *source_size == 0 && !size) + { + *result_size = 0; + *result_length_p = 0; + return true; + } + if ((result_elt_size > 0 && (mold->expr_type == EXPR_ARRAY || mold->rank)) || size) {
Index: gcc/testsuite/gfortran.dg/pr89492.f90 =================================================================== --- gcc/testsuite/gfortran.dg/pr89492.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/pr89492.f90 (working copy) @@ -0,0 +1,27 @@ +! { dg-do compile } +! +! PR fortran/89492 - Endless compilation of an invalid TRANSFER after r269177 +! Test error recovery for invalid uses of TRANSFER +! Test proper simplification for MOLD with size 0 +! +! Derived from original testcase by Dominique d'Humieres + +program bug4a + implicit none + type bug4 +! Intentionally left empty + end type bug4 + integer, parameter :: k = size(transfer('',[''])) ! k = 0 + integer, parameter :: i = len (transfer('',[''])) ! i = 0 + integer, parameter :: l = len (transfer('', '' )) ! l = 0 + integer, parameter :: m(k) = k + integer, parameter :: j(i) = i + integer, parameter :: n(l) = l + print *, k,i,l,m,j,n + print *, transfer(1,['']) ! { dg-error "shall not have storage size 0" } + print *, transfer(1, '' ) ! { dg-error "shall not have storage size 0" } + print *, size(transfer(1,[''])) ! { dg-error "shall not have storage size 0" } + print *, len (transfer(1, '' )) ! { dg-error "shall not have storage size 0" } + print *, size(transfer([1],[bug4()])) ! { dg-error "shall not have storage size 0" } + print *, transfer(transfer([1],[bug4()]),[1]) ! { dg-error "shall not have storage size 0" } +end program bug4a