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