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



Reply via email to