Bug 87937 - [8 Regression] LHS reallocation broken inside "select type" and "associate"
Summary: [8 Regression] LHS reallocation broken inside "select type" and "associate"
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 8.2.1
: P4 normal
Target Milestone: 8.3
Assignee: Paul Thomas
URL:
Keywords: wrong-code
: 88412 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-11-08 11:21 UTC by Tomáš Trnka
Modified: 2019-01-25 18:48 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 8.2.0, 9.0
Known to fail: 8.2.1
Last reconfirmed: 2018-11-08 00:00:00


Attachments
Original tree dump from 8.2.1 20181011 (2.77 KB, text/plain)
2018-11-08 12:24 UTC, Tomáš Trnka
Details
Original tree dump after removing the offending check (2.99 KB, text/plain)
2018-11-08 12:25 UTC, Tomáš Trnka
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tomáš Trnka 2018-11-08 11:21:39 UTC
The fix for pr85954 broke LHS reallocation inside "select type" blocks. The following program segfaults with current 8.2 branch (including the system compiler 8.2.1 20181011 on my Fedora 29):

program lhsalloc
   type, abstract :: A
      real, allocatable :: x(:)
   end type

   type, extends(A) :: B
   end type

   class(A), allocatable :: t
   real :: y(4)

   y = 1

   allocate(B::t)

   select type (t)
   type is (B)
      t%x = y
   end select

   write(*,*) allocated(t%x)
end program

The code to allocate t%x is simply never generated.

Partially reverting the offending change by removing these two lines from gfc_is_reallocatable_lhs fixes the issue:

if (sym->attr.associate_var)
  return false;

Although pr87625 sounds related, its fix doesn't help here because the associate_var check comes earlier.
Comment 1 Dominique d'Humieres 2018-11-08 11:57:05 UTC
> The code to allocate t%x is simply never generated.

How do you see that?

WORKSFORME on darwin.
Comment 2 Tomáš Trnka 2018-11-08 12:16:13 UTC
(In reply to Dominique d'Humieres from comment #1)
> > The code to allocate t%x is simply never generated.
> 
> How do you see that?
> 
> WORKSFORME on darwin.

Weird, I wouldn't expect the frontend to behave in a platform-specific way. What version are you using to test? (8.2.0 is not affected. I haven't actually tried it with 9, but AFAICS the code is the same.)

Running "gfortran -fdump-tree-original lhsalloc.f90" with and without the associate_var check produces the two attached files, with the allocation obviously missing from the bad one.
Comment 3 Tomáš Trnka 2018-11-08 12:24:22 UTC
Created attachment 44972 [details]
Original tree dump from 8.2.1 20181011
Comment 4 Tomáš Trnka 2018-11-08 12:25:07 UTC
Created attachment 44973 [details]
Original tree dump after removing the offending check
Comment 5 Tomáš Trnka 2018-11-26 14:31:25 UTC
Could you please kindly suggest what do I need to do to get this out of WAITING? I will gladly assist with any debugging and testing, but I'm not well versed enough with GCC internals to fix the underlying issue myself.

Looks like reallocation is also broken inside "associate" constructs. The following testcase from pr85954 crashes (when compiled without optimization) because no allocation code is generated at all. 

$ cat pr85954-z1.f90
program p
   character(:), allocatable :: z(:)
   call s(z)
contains
   subroutine s(x)
      character(:), allocatable :: x(:)
      associate (y => x)
         y = ['abc']
      end associate
      print *, allocated(x), size(x), len(x), x
   end
end
$ gfortran -g -fdump-tree-original pr85954-z1.f90 
$ grep alloc pr85954-z1.f90.003t.original 
$ ./a.out 
 F           0  1002358272
$ ./a.out      

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x7fed77d6471e in ???
#1  0x7fed77d638d3 in ???
#2  0x7fed779d55bf in ???
#3  0x7fed77afef0d in ???
#4  0x4012d8 in s
        at /home/trnka/adf/test/gcc-lhs-realloc-87937/pr85954-z1.f90:8
#5  0x401498 in p
        at /home/trnka/adf/test/gcc-lhs-realloc-87937/pr85954-z1.f90:3
#6  0x4014ce in main
        at /home/trnka/adf/test/gcc-lhs-realloc-87937/pr85954-z1.f90:3
Segmentation fault (core dumped)

The issue is less evident at -O1 and above, although the generated code is just as incorrect. It just doesn't segfault that much but valgrind shows a lot of uninitialized value errors all over the place.

The variant without an "associate" construct (z2.f90 in pr85954) works fine.
Comment 6 Tomáš Trnka 2018-11-26 14:34:07 UTC
The above is from GNU Fortran (GCC) 8.2.1 20181126
Comment 7 Dominique d'Humieres 2018-11-27 15:24:45 UTC
> Could you please kindly suggest what do I need to do to get this out of WAITING? ...

AFAIK you can do it yourself.

WAITING is not a punishment, it just mean that some feedback is needed, most of the time from the reporter, but sometimes from the maintainers. In this case it meant that at looked at the PR, but was unable to confirm it.

Now I get a segfault at runtime for the test in comment 5, likely caused by revision r257363 (pr84115).
Comment 8 Tomáš Trnka 2018-11-27 15:57:07 UTC
(In reply to Dominique d'Humieres from comment #7)
> > Could you please kindly suggest what do I need to do to get this out of WAITING? ...
> 
> AFAIK you can do it yourself.
> 
> WAITING is not a punishment, it just mean that some feedback is needed, most
> of the time from the reporter, but sometimes from the maintainers. In this
> case it meant that at looked at the PR, but was unable to confirm it.

OK, sorry for the noise then, I just found no way to change it myself. The only statuses offered in the drop-down for me were WAITING and RESOLVED.

> Now I get a segfault at runtime for the test in comment 5, likely caused by
> revision r257363 (pr84115).

OK, sounds like it might be an unrelated issue to the one I'm seeing. The following variant of that test crashes for me as well, even though there aren't any allocatable character strings in it. There's still no allocation code generated.

program p
   integer, allocatable :: z(:)
   call s(z)
contains
   subroutine s(x)
      integer, allocatable :: x(:)
      associate (y => x)
         y = [1, 2, 3]
      end associate
      print *, allocated(x), size(x), x
   end
end

In case this turns out to be an unrelated issue, could you double-check if you get a call to malloc() with the original test in my first post?
Comment 9 Dominique d'Humieres 2018-11-27 16:10:59 UTC
> OK, sounds like it might be an unrelated issue to the one I'm seeing. The
> following variant of that test crashes for me as well, even though there aren't
> any allocatable character strings in it. There's still no allocation code
> generated.

I got a segfault with this test since at least 4.8.5 up to trunk (9.0).
Comment 10 Paul Thomas 2018-11-27 20:12:41 UTC
(In reply to Dominique d'Humieres from comment #9)
> > OK, sounds like it might be an unrelated issue to the one I'm seeing. The
> > following variant of that test crashes for me as well, even though there aren't
> > any allocatable character strings in it. There's still no allocation code
> > generated.
> 
> I got a segfault with this test since at least 4.8.5 up to trunk (9.0).

From F2018:11.1.3.3

"Within an ASSOCIATE, CHANGE TEAM, or SELECT TYPE construct, each associating entity has the same rank as its associated selector. The lower bound of each dimension is the result of the intrinsic function LBOUND (16.9.109) applied to the corresponding dimension of selector. The upper bound of each dimension is one less than the sum of the lower bound and the extent. The associating entity does not have the ALLOCATABLE or POINTER attributes; it has the TARGET attribute if and only if the selector is a variable and has either the TARGET or POINTER attribute."

As I read that, or its equivalent in earlier standards, reallocation on assignment cannot occur for the likes of the testcase in comments #5 and #8. I guess that we have to think of a suitable runtime check to flag this up. How do the other brands behave?

However, I think that the original testcase is valid and that the allocation on assignment should occur. I will take this but it joins an ever increasing number of bugs that I have on my TODO list.

Paul
Comment 11 Tomáš Trnka 2018-11-28 11:35:23 UTC
(In reply to Paul Thomas from comment #10)
> As I read that, or its equivalent in earlier standards, reallocation on
> assignment cannot occur for the likes of the testcase in comments #5 and #8.

Good catch, I kinda suspected this may be the case. I just pulled the testcase from pr85954, assuming that it used to work at some point.

> I guess that we have to think of a suitable runtime check to flag this up.
> How do the other brands behave?

ifort 18.0.3 accepts the character(:) testcase in comment #5, but the assignment/allocation never happens, so that "x" stays unallocated, zero size, no segfault. However, the integer testcase in comment #8 reliably segfaults just like with gfortran.

> However, I think that the original testcase is valid and that the allocation
> on assignment should occur. I will take this but it joins an ever increasing
> number of bugs that I have on my TODO list.

I see. If I understand the situation correctly, the fix for pr85954 fixed an ICE on invalid Fortran code (causing a segfault at runtime instead), but also broke the perfectly valid code here. Then perhaps reverting the fix for pr85954 would be a sensible stop-gap for now?

I'm sorry for sounding a bit impatient, but this PR currently makes our (commercial) software unusable with GCC, so if it makes it into 8.3 and then into Linux distro updates, we're going to have some quite unhappy users. Right now, we only caught it on Fedora, which tracks the gcc-8 branch.
Comment 12 Dominique d'Humieres 2018-11-28 20:03:13 UTC
I finally got it: the problem has been introduced in trunk by revision r264358 and fixed by r264725.

On the GCC8 branch the problem has been introduced by r264404 and AFAICT the fix has not been back ported. If it helps I can try to apply the path in trunk to my gcc8 build.

Note that the problem is not present in 8.2.0.
Comment 13 Tomáš Trnka 2018-11-28 20:12:17 UTC
(In reply to Dominique d'Humieres from comment #12)
> I finally got it: the problem has been introduced in trunk by revision
> r264358 and fixed by r264725.

Good catch! (How could I have missed that?)

Backporting r264725 on top of the current gcc-8 branch fixes the issue for me. Thanks!
Comment 14 Dominique d'Humieres 2018-11-28 22:00:40 UTC
> Backporting r264725 on top of the current gcc-8 branch fixes the issue for me.

I changed the summary that the problem is fixed on trunk.
Comment 15 Martin Diehl 2018-12-08 16:45:53 UTC
*** Bug 88412 has been marked as a duplicate of this bug. ***
Comment 16 Paul Thomas 2019-01-25 18:48:58 UTC
The regression is fixed on 8- and 9-branches.

Paul