https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116388
Bug ID: 116388 Summary: [13/14/15 regression] Finalizer called on uninitialized components of intent(out) argument Product: gcc Version: 13.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: trnka at scm dot com Target Milestone: --- Created attachment 58935 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58935&action=edit testcase illustrating this issue This feels potentially related to PR115070 but it is probably not an exact duplicate; the proposed fix in PR115070 comment 9 does not fix this issue on current master branch. The attached testcase contains a type like this: type, public :: AType type(C_ptr) :: cptr = C_null_ptr logical :: cptr_invalid = .true. integer, allocatable :: x(:) contains final :: FinalizerA end type … impure elemental subroutine FinalizerA(self) type(AType), intent(inout) :: self if (.not. self%cptr_invalid) write(*,*) "A:", self%cptr end subroutine Nothing in the program ever sets "cptr_invalid" to .false., so "A:" should never be printed. However, compiling the testcase with gfortran 13.x and up produces a program which often prints "A: somerandomvalue" once. Looking at the tree dump, this is because the __final for CType creates a temporary "comp_byte_stride", which is only partially initialized (so the components of AType apart from x aren't initialized) but then calls FinalizerA on the whole a component. integer(kind=4) __final_finalizertestmodule_Ctype (struct array15_ctype & restrict array, integer(kind=8) byte_stride, logical(kind=1) fini_coarray) { struct btype comp_byte_stride; … try { comp_byte_stride.a.x.data = 0B; // no other components of comp_byte_stride are initialized here … finally { __builtin_free ((void *) strides); __builtin_free ((void *) sizes); desc.6.dtype = {.elem_len=80, .version=0, .rank=0, .type=5}; desc.6.data = (void * restrict) &comp_byte_stride.a; desc.6.span = (integer(kind=8)) desc.6.dtype.elem_len; __final_finalizertestmodule_Atype (&desc.6, 80, 1); Accessing uninitialized data at runtime is also confirmed using valgrind --tool=memcheck. "comp_byte_stride" was introduced by the following commit which went into 13.x. GCC 12 and older seems to be unaffected by this issue. commit d7caf313525a46f200d7f5db1ba893f853774aee Author: Paul Thomas <pa...@gcc.gnu.org> Date: Sat Mar 18 07:56:23 2023 +0000 Fortran: Fix bugs and missing features in finalization [PR37336] 2023-03-18 Paul Thomas <pa...@gcc.gnu.org> (BType in the testcase seems to be superfluous but removing it and putting AType straight into CType masks the issue somewhat, because the uninitialized data then happens to have the right value so that A: is never printed. However, the bug still seems to be there in the tree dump even without BType.)