Hi Tobias, I notice that your scalar allocation does not use reallocation at all. There is something not quite right there.
However, this just demonstrates one of the gotchas associated with pointers, especially where the target is allocatable, and has nothing to do with reallocation on assignment. Try this case, which does not use class assignment. implicit none (type, external) integer, pointer :: ptr(:) class(*), target, allocatable :: alloc(:) allocate(integer :: alloc(1)) select type(alloc) type is(integer) alloc = 67 ptr => alloc end select call assign(alloc) !print *, ptr ! This causes an invalid read of size 4 !if (ptr(1) /= 5) error stop 1 select type(alloc) type is(integer) print *, alloc if (associated (ptr, alloc)) then print *, ptr else print *, "ptr is no longer associated with assoc" end if !if (ptr(1) /= 5) error stop 2 end select deallocate(alloc) contains subroutine assign(x) class(*), allocatable :: x(:) if (allocated(x)) deallocate(x) allocate (x, source = [5]) end subroutine assign end [pault@pc30 pr83118]$ ./a.out 5 5 Interestingly, under valgrind the result is: 5 ptr is no longer associated with assoc Cheers Paul On Mon, 18 Nov 2019 at 10:24, Tobias Burnus <tob...@codesourcery.com> wrote: > > On 11/17/19 7:34 PM, Paul Richard Thomas wrote: > […] > Sorry for not yet reviewing the code, but the following caught my eye: > > (gfc_alloc_allocatable_for_assignment): […] > > Force reallocation of unlimited > > polymorphic lhs's. […] > > […] > > ! /* If the lhs is deferred length or unlimited polymorphic, assume that > > ! the element size changes and force a reallocation. */ > > ! if (expr1->ts.deferred || UNLIMITED_POLY (expr1)) > I wonder whether this assumption breaks code, which relies on a pointer > address not changing, cf. test case below. > > I think the standard does not state explicitly that no reallocation > happens, but I think it can be deduced. In any case, the reallocation is > only supposed to happen for (F2018, 10.2.1.3p1): > "If the variable is an allocated allocatable variable, it is deallocated > ifexpr is an array of different shape, any corresponding length type > parameter values of the variable andexprdiffer, or the variable is > polymorphic and the dynamic type or any corresponding kind type > parameter values of the variable andexpr differ." > > Cheers, > > Tobias > > implicit none (type, external) > integer, pointer :: ptr > class(*), target, allocatable :: alloc > allocate(integer :: alloc) > select type(alloc) > type is(integer) > alloc = 67 > ptr => alloc > end select > call assign(alloc) > !print *, ptr > if (ptr /= 5) error stop 1 > select type(alloc) > type is(integer) > !print *, alloc > if (ptr /= 5) error stop 2 > end select > contains > subroutine assign(x) > class(*), allocatable :: x > x = 5 > end subroutine assign > end > -- "If you can't explain it simply, you don't understand it well enough" - Albert Einstein