diff mbox series

PR 83975 Set character length to 0 if unknown

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

Commit Message

Janne Blomqvist Jan. 23, 2018, 9:29 a.m. UTC
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?

gcc/fortran/ChangeLog:

2018-01-23  Janne Blomqvist  <jb@gcc.gnu.org>

	PR 83975
	PR 83344
	* resolve.c (resolve_assoc_var): Set character length to zero if
	target length unknown.

gcc/testsuite/ChangeLog:

2018-01-23  Janne Blomqvist  <jb@gcc.gnu.org>

	PR 83975
	PR 83344
	* gfortran.dg/associate_31.f90: New test.
---
 gcc/fortran/resolve.c                      | 13 ++++++++-----
 gcc/testsuite/gfortran.dg/associate_31.f90 |  8 ++++++++
 2 files changed, 16 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/associate_31.f90

Comments

Thomas Koenig Jan. 23, 2018, 4:33 p.m. UTC | #1
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
Janne Blomqvist Jan. 23, 2018, 7:29 p.m. UTC | #2
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 mbox series

Patch

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