Dear all, the attached, rather simple patch adds the missing default-initialization of non-pointer, non-allocatable derived-type function results.
Regtested ok on x86_64-pc-linux-gnu, but needed two adjustments in the testsuite. One of them is easily explained by the fix, but the other one to gfortran.dg/pdt_26.f03 makes me scratch my head. The patch adds default-initialization and thus changes the count of __builtin_malloc in the tree dump, but not the __builtin_free count. Running the testcase under valgrind shows that no memleak occurs at -O1 and higher, but I get a minor leak at -O0 and -Og. The dump tree is the same at -O0 and -O1, which is nice. Any suggestions how to proceed? And is the patch OK for mainline? The PDT implementation may have latent issues, but that is just a guess. Thanks, Harald
From b75d3cb8321018f68b39e1799113bf7815bfab19 Mon Sep 17 00:00:00 2001 From: Harald Anlauf <anl...@gmx.de> Date: Thu, 29 Aug 2024 22:17:07 +0200 Subject: [PATCH] Fortran: default-initialization of derived-type function results [PR98454] gcc/fortran/ChangeLog: PR fortran/98454 * resolve.cc (resolve_symbol): Add default-initialization of non-allocatable, non-pointer derived-type function results. gcc/testsuite/ChangeLog: PR fortran/98454 * gfortran.dg/alloc_comp_class_4.f03: Remove bogus pattern. * gfortran.dg/pdt_26.f03: Adjust expected count. * gfortran.dg/derived_result_3.f90: New test. --- gcc/fortran/resolve.cc | 3 + .../gfortran.dg/alloc_comp_class_4.f03 | 2 +- .../gfortran.dg/derived_result_3.f90 | 158 ++++++++++++++++++ gcc/testsuite/gfortran.dg/pdt_26.f03 | 2 +- 4 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/derived_result_3.f90 diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index 5db327cd12b..a78e9b7daf7 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -17262,6 +17262,9 @@ resolve_symbol (gfc_symbol *sym) /* Mark the result symbol to be referenced, when it has allocatable components. */ sym->result->attr.referenced = 1; + else if (a->function && !a->pointer && !a->allocatable && sym->result) + /* Default initialization for function results. */ + apply_default_init (sym->result); } if (sym->ts.type == BT_CLASS && sym->ns == gfc_current_ns diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 b/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 index 3118b552a30..4a55d73b245 100644 --- a/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 +++ b/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 @@ -71,7 +71,7 @@ contains allocatable :: t_init end function - type(t) function static_t_init() ! { dg-warning "not set" } + type(t) function static_t_init() end function end module test_pr58586_mod diff --git a/gcc/testsuite/gfortran.dg/derived_result_3.f90 b/gcc/testsuite/gfortran.dg/derived_result_3.f90 new file mode 100644 index 00000000000..4b28f7e28c9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/derived_result_3.f90 @@ -0,0 +1,158 @@ +! { dg-do run } +! PR fortran/98454 - default-initialization of derived-type function results + +program test + implicit none + type t + integer :: unit = -1 + end type t + type u + integer, allocatable :: unit(:) + end type u + type(t) :: x, x3(3) + type(u) :: y, y4(4) + + ! Scalar function result, DT with default initializer + x = t(42) + if (x% unit /= 42) stop 1 + x = g() + if (x% unit /= -1) stop 2 + x = t(42) + x = f() + if (x% unit /= -1) stop 3 + x = t(42) + x = h() + if (x% unit /= -1) stop 4 + x = t(42) + x = k() + if (x% unit /= -1) stop 5 + + ! Array function result, DT with default initializer + x3 = t(13) + if (any (x3% unit /= 13)) stop 11 + x3 = f3() + if (any (x3% unit /= -1)) stop 12 + x3 = t(13) + x3 = g3() + if (any (x3% unit /= -1)) stop 13 + x3 = t(13) + x3 = h3() + if (any (x3% unit /= -1)) stop 14 + x3 = t(13) + x3 = k3() + if (any (x3% unit /= -1)) stop 15 + + ! Scalar function result, DT with allocatable component + y = u() + if (allocated (y% unit)) stop 21 + allocate (y% unit(42)) + y = m() + if (allocated (y% unit)) stop 22 + allocate (y% unit(42)) + y = n() + if (allocated (y% unit)) stop 23 + allocate (y% unit(42)) + y = o() + if (allocated (y% unit)) stop 24 + allocate (y% unit(42)) + y = p() + if (allocated (y% unit)) stop 25 + + ! Array function result, DT with allocatable component + y4 = u() + if (allocated (y4(1)% unit)) stop 31 + allocate (y4(1)% unit(42)) + y4 = m4() + if (allocated (y4(1)% unit)) stop 32 + y4 = u() + allocate (y4(1)% unit(42)) + y4 = n4() + if (allocated (y4(1)% unit)) stop 33 + + y4 = u() + allocate (y4(1)% unit(42)) + y4 = o4() + if (allocated (y4(1)% unit)) stop 34 + y4 = u() + allocate (y4(1)% unit(42)) + y4 = p4() + if (allocated (y4(1)% unit)) stop 35 + +contains + + ! Function result not referenced within function body + function f() + type(t) :: f + end function f + + function k() result (f) + type(t) :: f + end function k + + ! Function result referenced within function body + function g() + type(t) :: g + if (g% unit /= -1) stop 41 + end function g + + function h() result (g) + type(t) :: g + if (g% unit /= -1) stop 42 + end function h + + ! Function result not referenced within function body + function f3 () + type(t) :: f3(3) + end function f3 + + function k3() result (f3) + type(t) :: f3(3) + end function k3 + + ! Function result referenced within function body + function g3() + type(t) :: g3(3) + if (any (g3% unit /= -1)) stop 43 + end function g3 + + function h3() result (g3) + type(t) :: g3(3) + if (any (g3% unit /= -1)) stop 44 + end function h3 + + function m() + type(u) :: m + end function m + + function n() result (f) + type(u) :: f + end function n + + function o() + type(u) :: o + if (allocated (o% unit)) stop 71 + end function o + + function p() result (f) + type(u) :: f + if (allocated (f% unit)) stop 72 + end function p + + function m4() + type(u) :: m4(4) + end function m4 + + function n4() result (f) + type(u) :: f(4) + end function n4 + + function o4() + type(u) :: o4(4) + if (allocated (o4(1)% unit)) stop 73 + end function o4 + + function p4() result (f) + type(u) :: f(4) + if (allocated (f(1)% unit)) stop 74 + end function p4 +end diff --git a/gcc/testsuite/gfortran.dg/pdt_26.f03 b/gcc/testsuite/gfortran.dg/pdt_26.f03 index 59ddcfb6cc4..b7e3bb600b4 100644 --- a/gcc/testsuite/gfortran.dg/pdt_26.f03 +++ b/gcc/testsuite/gfortran.dg/pdt_26.f03 @@ -43,4 +43,4 @@ program test_pdt if (any (c(1)%foo .ne. [13,15,17])) STOP 2 end program test_pdt ! { dg-final { scan-tree-dump-times "__builtin_free" 8 "original" } } -! { dg-final { scan-tree-dump-times "__builtin_malloc" 8 "original" } } +! { dg-final { scan-tree-dump-times "__builtin_malloc" 9 "original" } } -- 2.35.3