Message ID | 1516699780-4970-1-git-send-email-blomqvist.janne@gmail.com |
---|---|
State | New |
Headers | show |
Series | PR 83975 Set character length to 0 if unknown | expand |
Hi Janne, > When associating a variable of type character, if the length of the > target isn't known, set it to zero rather than leaving it unset. This > is not a complete fix for making associate of characters work > properly, but papers over an ICE in the middle-end. See PR 83344 for > more details. > > Regtested on x86_64-pc-linux-gnu, Ok for trunk? Does the code which is accepted then execute correctly? Personally, I would prefer an ICE over a silent wrong-code. Regards Thomas
On Tue, Jan 23, 2018 at 6:33 PM, Thomas Koenig <tkoenig@netcologne.de> wrote: > Hi Janne, > >> When associating a variable of type character, if the length of the >> target isn't known, set it to zero rather than leaving it unset. This >> is not a complete fix for making associate of characters work >> properly, but papers over an ICE in the middle-end. See PR 83344 for >> more details. >> >> Regtested on x86_64-pc-linux-gnu, Ok for trunk? > > > Does the code which is accepted then execute correctly? Hmm, prompted by your question I did some investigating, and I present to you evidence of GFortran being a quantum mechanical compiler (spooky action at a distance!): Consider the slightly fleshed out testcase from PR 83975: program foo call s("foo") contains subroutine s(x) character(*) :: x print *, "X:", x, ":ENDX" print *, "len(x): ", len(x) ! associate (y => x) ! print *, "Y:", y, ":ENDY" ! print *, "len(y): ", len(y) ! end associate end subroutine s end program foo With the associate stuff commented out, it's fairly bog-standard stuff, and the output is the expected: X:foo:ENDX len(x): 3 Now, incorporating the commented out associate block, and the result is: X::ENDX len(x): 0 Y::ENDY len(y): 0 So the associate construct manages to somehow break the variable X in the outer scope!
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index a2b892a..f3fc3ca 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -8634,11 +8634,14 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target) if (!sym->ts.u.cl) sym->ts.u.cl = target->ts.u.cl; - if (!sym->ts.u.cl->length && !sym->ts.deferred - && target->expr_type == EXPR_CONSTANT) - sym->ts.u.cl->length - = gfc_get_int_expr (gfc_charlen_int_kind, - NULL, target->value.character.length); + if (!sym->ts.u.cl->length && !sym->ts.deferred) + /* TODO: Setting the length to zero if the expression isn't + constant is probably not correct, but at this point we + don't have any better idea what it should be either. */ + sym->ts.u.cl->length = + gfc_get_int_expr (gfc_charlen_int_kind, NULL, + target->expr_type == EXPR_CONSTANT ? + target->value.character.length : 0); } /* If the target is a good class object, so is the associate variable. */ diff --git a/gcc/testsuite/gfortran.dg/associate_31.f90 b/gcc/testsuite/gfortran.dg/associate_31.f90 new file mode 100644 index 0000000..75774c8 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/associate_31.f90 @@ -0,0 +1,8 @@ +! { dg-do compile } +! PR 83975, see also PR 83344 +! Testcase contributed by Gerhard Steinmetz +subroutine s(x) + character(*) :: x + associate (y => x) + end associate +end subroutine s