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);
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?
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:
program foo
implicit none
complex :: cmp(3) = (3.45,6.78)
real, pointer :: pp(:)
integer, allocatable :: aa(:)
class(*), allocatable :: uu(:), vv(:)
type t ! pseudo "complex" type
real :: re
real :: im
end type t
type ci ! "complex integer" type
integer :: re
integer :: im
end type ci
type u
type(t) :: tt(3)
type(ci) :: ii(3)
end type u
type(u) :: cc
character(3) :: str(3) = ["abc","def","ghi"]
character(:), allocatable :: ac(:)
allocate (ac, source=str(1::2)(2:3))
print *, str(1::2)(2:3)
call my_print (ac)
cc% tt% re = cmp% re
cc% tt% im = cmp% im
cc% ii% re = nint (cmp% re)
cc% ii% im = nint (cmp% im)
print *, "re=", cc% tt% re
print *, "im=", cc% tt% im
allocate (pp, source = cc% tt% re)
print *, pp
allocate (uu, source = cc% tt% im)
call my_print (uu)
allocate (vv, source = cc% ii% im)
call my_print (vv)
contains
subroutine my_print (x)
class(*), intent(in) :: x(:)
select type (x)
type is (real)
print *, "'real':", x
type is (integer)
print *, "'integer':", x
type is (character(*))
print *, "'character':", x
end select
end subroutine my_print
end
Cheers,
Harald