On Thu, Feb 22, 2024 at 09:22:37PM +0100, Harald Anlauf wrote:
> Hi Steve!
> 
> On 2/22/24 01:52, Steve Kargl wrote:
> > On Wed, Feb 21, 2024 at 01:42:32PM -0800, Steve Kargl wrote:
> > > On Wed, Feb 21, 2024 at 10:20:43PM +0100, Harald Anlauf wrote:
> > > > On 2/21/24 22:00, Steve Kargl wrote:
> > > > > memleak vs ICE.  I think I'll take one over the other.
> > > > > Probably need to free code->expr3 before the copy.
> > > > 
> > > > Yep.
> > > > 
> > > > > I tried gfc_replace_expr in an earlier patch.  It did not
> > > > > work.
> > 
> > I tried freeing code->expr3 before assigning the new expression.
> > That leads to
> > 
> > % gfcx -c ~/gcc/gccx/gcc/testsuite/gfortran.dg/allocate_with_source_28.f90
> > pid 69473 comm f951 has trashed its stack, killing
> > gfortran: internal compiler error: Illegal instruction signal terminated 
> > program f951
> 
> Right.  I also don't see what the lifetimes of the expressions are.
> 
> But is the gfc_copy_expr really needed?  Wouldn't the following suffice?
> 
>   code->expr3 = gfc_get_parentheses (code->expr3);

It's been awhile since I use gfc_copy_expr, gfc_replace_expr, etc.
I did not try the above.  If that works, then we should use that
for simplicity.

> > If I don't free code->expr3 but simply assign the new
> > expression from gfc_get_parentheses(), your example
> > now compiles are executes are expected.  It now
> > allocate_with_source_28.f90.  Caveat:  I don't know
> > how to test the CLASS uu.
> > 
> > > > > > - it still fails on the following code, because the traversal
> > > > > >     of the refs is incomplete / wrong:
> > > > > > 
> > > > > > program foo
> > > > > >      implicit none
> > > > > >      complex               :: cmp(3)
> > > > > >      real, pointer         :: pp(:)
> > > > > >      class(*), allocatable :: uu(:)
> > > > > >      type t
> > > > > >         real :: re
> > > > > >         real :: im
> > > > > >      end type t
> > > > > >      type u
> > > > > >         type(t) :: tt(3)
> > > > > >      end type u
> > > > > >      type(u) :: cc
> > > > > > 
> > > > > >      cmp = (3.45,6.78)
> > > > > >      cc% tt% re = cmp% re
> > > > > >      cc% tt% im = cmp% im
> > > > > >      allocate (pp, source = cc% tt% im)       ! ICE
> > > > > 
> > > > > cc%tt%im isn't a complex-part-ref, so this seems to
> > > > > be a different (maybe related) issue.  Does the code
> > > > > compile with 'source = (cc%tt%im)'?  If so, perhaps,
> > > > > detecting a component reference and doing the simply
> > > > > wrapping with parentheses can be done.
> > > > 
> > > > Yes, that's why I tried to make up the above example.
> > > > I think %re and %im are not too special, they work
> > > > here pretty much like component refs elsewhere.
> > > > 
> > > 
> > > I see.  The %re and %im complex-part-ref correspond to
> > > ref->u.i == INQUIRY_RE and INQUIRY_IM, respectively.
> > > A part-ref for a user-defined type doesn't have an
> > > INQUIRY_xxx, so we'll need to see if there is a way to
> > > easily identify, e.g., cc%tt%re from your testcase.
> > 
> > The attach patch uses ref->type == REF_COMPONENT to deal
> > with the above code.
> 
> I actually wanted to draw your attention away from the
> real/complex stuff, because that is not really the point.
> When do we actually need to enforce the parentheses?

This is essentially my concern.  I was inserting parentheses
only if I determined they were needed (to avoid unnecessary
temporary variable).  The code paththat enters the else portion
of the following if-else-stmt, where a temporary is created.
That is, 

allocate(x, source=z%re) becomes allocate(x, source=(z%re))
and from code generation viewpoint this is

tmp = (z%re)
allocate(x, sourcer=tmp)
deallocate(tmp)

> I tried the following, and it seems to work:
> 
>       if (code->expr3->expr_type == EXPR_VARIABLE
>         && is_subref_array (code->expr3))
>       code->expr3 = gfc_get_parentheses (code->expr3);
> 
> (Beware: this is not regtested!)
> 
> On the positive side, it not only seems to fix the cases in question,
> but also substring references etc., like the following:

If the above passes a regression test, then by all means we should
use it.  I did not consider the substring case.  Even if unneeded
parentheses are inserted, which may cause generation of a temporary
variable, I hope users are not using 'allocate(x,source=z%re)' is
some deeply nested crazy loops structure.

BTW, my patch and I suspect your improved patch also
fixes 'allocate(x,mold=z%re)'.  Consider,

   complex z(3)
   real, allocatable :: x(:)
   z = 42
   allocate(x, mold=z%re)
   print *, size(x)
   end

% gfortran13 -o z a.f90
a.f90:9:25:

    9 |    allocate(x, mold=z%re)
      |                         1
internal compiler error: in retrieve_last_ref, at fortran/trans-array.cc:6070
0x247d7a679 __libc_start1
        /usr/src/lib/libc/csu/libc_start1.c:157

% gfcx -o z a.f90 && ./z
           3



-- 
Steve

Reply via email to