Hello Harald,

Your testcase opened up a can of worms. The fix for the parentheses is
straightforward:

   /* Assign the 'data' of a class object to a derived type.  */
   if (lhs->ts.type == BT_DERIVED
       && rhs->ts.type == BT_CLASS
-      && rhs->expr_type != EXPR_ARRAY)
+      && (rhs->expr_type != EXPR_ARRAY
+         && rhs->expr_type != EXPR_OP))
     gfc_add_data_component (rhs);

   /* Make sure there is a vtable and, in particular, a _copy for the

However, the following has faults as shown, with or without parentheses:
program p
   integer :: i
   type :: t
     integer, allocatable :: i(:)
   end type
   type (t), allocatable :: src(:), ans(:)
   src = [t([1,2]), t([3,4])] ! Leaks memory 16 bytes in 2 blocks;
                              ! familiar from PDT memory leaks :-(
   ans = f(src)
   do i = 1,2
     print *, "src = ", src(i)%i, "ans = ",ans(i)%i
     deallocate (ans(i)%i, src(i)%i)
   enddo
   deallocate (ans, src)
contains
   function f(x) result(z)
     class(t), intent(inout) :: x(:)
     type(t)  :: z (size(x))
     class(t), allocatable :: a(:)
     class(t), allocatable :: b(:)
     allocate (a(size(x)))
     select type (x)
       type is (t)
!         a = x                                ! Mangles src and causes
                                               ! double free at line 11
     end select
     b = x
     z = (b)                                  ! ICE, without patch
   end
end

Cheers

Paul

On Thu, 2 Apr 2026 at 19:49, Harald Anlauf <[email protected]> wrote:
>
> Hi Paul,
>
> On 4/2/26 11:36, Paul Richard Thomas wrote:
> > Hi All,
> >
> > The attached fixes the PR and cures the memory leak in pr105168.
> >
> > Regtested on FC43/x86_64. OK for mainline and later backporting?
>
> as you say, the patch is indeed not too pretty, although
> it works with the testcase that comes with it.
>
> It does not fix the following variation for me:
>
> program p
>    type :: t
>    end type
> contains
>    recursive function f(x) result(z)
>      class(*), intent(in) :: x(:)
>      type(t)  :: z (size(x))
>      class(t), allocatable :: a(:)
>      class(t), allocatable :: b(:)
>      allocate (a(size(x)))
>      b = f((a))
>      z = b   ! no ICE
>      z = (b) ! ICE
>    end
> end
>
> % gfc-16 pr100155.f90
> f951: internal compiler error: Segmentation fault
> 0x26ba694 internal_error(char const*, ...)
>          ../../gcc-trunk/gcc/diagnostic-global-context.cc:787
> 0x127c0af crash_signal
>          ../../gcc-trunk/gcc/toplev.cc:325
> 0xa2bc63 gfc_add_component_ref(gfc_expr*, char const*)
>          ../../gcc-trunk/gcc/fortran/class.cc:217
> 0xaf6642 resolve_ordinary_assign
>          ../../gcc-trunk/gcc/fortran/resolve.cc:13223
> 0xaf6642 gfc_resolve_code(gfc_code*, gfc_namespace*)
>          ../../gcc-trunk/gcc/fortran/resolve.cc:14336
> 0xaf7c62 resolve_codes
>          ../../gcc-trunk/gcc/fortran/resolve.cc:20289
> 0xaf7ba3 resolve_codes
>          ../../gcc-trunk/gcc/fortran/resolve.cc:20270
> 0xaf7d02 gfc_resolve(gfc_namespace*)
>          ../../gcc-trunk/gcc/fortran/resolve.cc:20324
> 0xae2ac9 resolve_all_program_units
>          ../../gcc-trunk/gcc/fortran/parse.cc:7531
> 0xae2ac9 gfc_parse_file()
>          ../../gcc-trunk/gcc/fortran/parse.cc:7793
> 0xb41caf gfc_be_parse_file
>          ../../gcc-trunk/gcc/fortran/f95-lang.cc:247
>
> You might proceed nevertheless for 16-trunk, and either keep
> an eye on the above, or add it to the present (or a new) PR.
> (It could be a different existing PR; haven't searched bugzilla.
> In that case just go ahead.)
>
> Thanks,
> Harald
>
>

Reply via email to