https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92178
kargl at gcc dot gnu.org changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P4 Status|UNCONFIRMED |NEW Last reconfirmed| |2019-10-22 CC| |kargl at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #2 from kargl at gcc dot gnu.org --- Compiling the code with -fdump-tree-original and stripping out the unessential intermediate code gives assign (struct array01_integer(kind=4) & restrict a, integer(kind=4) b) { } foo () { if ((integer(kind=4)[0:] * restrict) a.data != 0B) { __builtin_free ((void *) a.data); (integer(kind=4)[0:] * restrict) a.data = 0B; } assign (&a, (*(integer(kind=4)[0:] * restrict) a.data)[a.offset + 1]); } The effect of the intent(out) in assign is to deallocate the code on entry to assign. This is done with the if-block. The side-effect of evaluating the first dummy argument is that 'a' in the expression of the 2nd dummy argument is undefined. F2018 (well 18-007r1) page 308: If a dummy argument has INTENT (OUT) or INTENT (INOUT), the actual argument shall be definable. If a dummy argument has INTENT (OUT) and its associated actual argument is allocated, the actual argument is deallocated on procedure invocation (9.7.3.2). then later 15.5.2.13 Restrictions on entities associated with dummy arguments While an entity is associated with a dummy argument, the following restrictions hold. (1) Action that affects the allocation status of the entity or a subobject thereof shall be taken through the dummy argument. (2) If the allocation status of the entity or a subobject thereof is affected through the dummy argument, then at any time during the invocation and execution of the procedure, either before or after the allocation or deallocation, it shall be referenced only through the dummy argument. It seems that code is non-conforming.