https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110626

--- Comment #12 from Tomáš Trnka <trnka at scm dot com> ---
Created attachment 64834
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64834&action=edit
Alternative testcase

FWIW, I discussed this exact issue in a support ticket with Intel a year ago
(together with another issue where Intel compilers failed to default-initialize
the intent(out) LHS argument for the defined assignment so the body of the
defined assignment saw the state produced by the finalizer; this issue has
since been fixed). My testcase was very similar to Javier's example (an amazing
example of convergent evolution), and Intel's reasoning for deliberately making
two finalizations matches what Chris has just outlined here:

> We believe the behavior of the ifx compiler is correct for this test.
> 
> For the first assignment, y = x, y is finalizable per 7.5.6.1 Final 
> subroutines, p2:
>                 A derived type if finalizable if and only if it has a final
>                 subroutine or a nonpointer, nonallocatable component of
>                 finalizable type. A nonpointer data entity is finalizable
>                 if and only if it is of finalizable type. No other entity
>                 is finalizable.> 
> 7.5.6.3 When finalization occurs p1 states:
>                 When an intrinsic assignment statement is executed, if the
>                 variable is not an unallocated allocatable variable, it is
>                 finalized after evaluation of expr and before the
>                 definition of the variable.> 
> In the assignment y=x, y is finalizable, so it is finalized after evaluation
> of x but before assignment to y.> 
> In the second assignment, ya=xa, ya has a noncoarray allocatable component. 
> 10.2.1.3 Interpretation of intrinsic assignment p15 states:
>                 . . . For a noncoarray allocatable component the following
>                 sequence of operations is applied.> 
> 1.      If the component of the variable is allocated, it is deallocated.
> 
> 2.      If the component of the value of expr is allocated, the
> corresponding component of the variable is allocated with the same dynamic
> type and type parameters as the component of expr. … The value of the
> component of the value of expr is then assigned to the corresponding
> component of the variable using defined assignment if the declared type of
> the component has a type-bound defined assignment consistent with the
> component, and intrinsic assignment for the dynamic type of that component
> otherwise.> 
> ya%f, an allocated allocatable component of ya is thus deallocated. 7.5.6.3 
> When finalization occurs p2 states:
>                 … When an allocatable entity is deallocated, it is finalized
>                 unless it is the variable in an intrinsic assignment
>                 statement.> 
> Thus, ya%f is finalized. This covers the initial finalization of both y and
> ya. y and ya then assigned the values of x and xa, respectively.> 
> 10.2.1.3 Interpretation of intrinsic assignments p15 states:
>                 . . . For a noncoarray allocatable component the following
>                 sequence of operations is applied.>     
>     If the component of the variable is allocated, it is deallocated.
> 
> 2.      If the component of the value of expr is allocated, the
> corresponding component of the variable is allocated with the same dynamic
> type and type parameters as the component of expr. … The value of the
> component of the value of expr is then assigned to the corresponding
> component of the variable using defined assignment if the declared type of
> the component has a type-bound defined assignment consistent with the
> component, and intrinsic assignment for the dynamic type of that component
> otherwise.> 
>  __
> 
> Both y%f and ya%f will be assigned using the type bound assign procedure 
> Assign. y%f and ya%f become argument associated with the first dummy argument 
> of Assign, which is a non-allocatable, INTENT (OUT) dummy argument. Section 
> 7.5.6.3 When finalization occurs p7 states:
>  __
>  
>                When a procedure is invoked, a nonpointer, nonallocatable,
>                INTENT (OUT) dummy argument of that procedure is finalized
>                before it becomes defined.> 
> This is where the second finalization of both y%f and ya%f occurs.

Reply via email to