https://gcc.gnu.org/g:0100ea2b4eb1c83972e0db07503a7cfe8a38932e

commit r14-11805-g0100ea2b4eb1c83972e0db07503a7cfe8a38932e
Author: Harald Anlauf <anl...@gmx.de>
Date:   Thu May 15 21:07:07 2025 +0200

    Fortran: default-initialization and functions returning derived type 
[PR85750]
    
    Functions with non-pointer, non-allocatable result and of derived type did
    not always get initialized although the type had default-initialization,
    and a derived type component had the allocatable or pointer attribute.
    Rearrange the logic when to apply default-initialization.
    
            PR fortran/85750
    
    gcc/fortran/ChangeLog:
    
            * resolve.cc (resolve_symbol): Reorder conditions when to apply
            default-initializers.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/alloc_comp_auto_array_3.f90: Adjust scan counts.
            * gfortran.dg/alloc_comp_class_3.f03: Remove bogus warnings.
            * gfortran.dg/alloc_comp_class_4.f03: Likewise.
            * gfortran.dg/allocate_with_source_14.f03: Adjust scan count.
            * gfortran.dg/derived_constructor_comps_6.f90: Likewise.
            * gfortran.dg/derived_result_5.f90: New test.
    
    (cherry picked from commit d31ab498b12ebbe4f50acb2aa240ff92c73f310c)

Diff:
---
 gcc/fortran/resolve.cc                             |   7 +-
 .../gfortran.dg/alloc_comp_auto_array_3.f90        |   4 +-
 gcc/testsuite/gfortran.dg/alloc_comp_class_3.f03   |   3 +-
 gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03   |   5 +-
 .../gfortran.dg/allocate_with_source_14.f03        |   2 +-
 .../gfortran.dg/derived_constructor_comps_6.f90    |   2 +-
 gcc/testsuite/gfortran.dg/derived_result_5.f90     | 123 +++++++++++++++++++++
 7 files changed, 134 insertions(+), 12 deletions(-)

diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 4d8484a36f12..10a9e58b287a 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -17134,15 +17134,16 @@ skip_interfaces:
          || (a->dummy && !a->pointer && a->intent == INTENT_OUT
              && sym->ns->proc_name->attr.if_source != IFSRC_IFBODY))
        apply_default_init (sym);
+      else if (a->function && !a->pointer && !a->allocatable && !a->use_assoc
+              && sym->result)
+       /* Default initialization for function results.  */
+       apply_default_init (sym->result);
       else if (a->function && sym->result && a->access != ACCESS_PRIVATE
               && (sym->ts.u.derived->attr.alloc_comp
                   || sym->ts.u.derived->attr.pointer_comp))
        /* 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_auto_array_3.f90 
b/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_3.f90
index 2af089e84e8d..d0751f3d3eba 100644
--- a/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_3.f90
+++ b/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_3.f90
@@ -25,6 +25,6 @@ contains
     allocate (array(1)%bigarr)
   end function
 end
-! { dg-final { scan-tree-dump-times "builtin_malloc" 3 "original" } }
+! { dg-final { scan-tree-dump-times "builtin_malloc" 4 "original" } }
 ! { dg-final { scan-tree-dump-times "builtin_free" 3 "original" } }
-! { dg-final { scan-tree-dump-times "while \\(1\\)" 4 "original" } }
+! { dg-final { scan-tree-dump-times "while \\(1\\)" 5 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_class_3.f03 
b/gcc/testsuite/gfortran.dg/alloc_comp_class_3.f03
index 0753e33d535d..8202d783621c 100644
--- a/gcc/testsuite/gfortran.dg/alloc_comp_class_3.f03
+++ b/gcc/testsuite/gfortran.dg/alloc_comp_class_3.f03
@@ -45,11 +45,10 @@ contains
     type(c), value :: d
   end subroutine
 
-  type(c) function c_init()  ! { dg-warning "not set" }
+  type(c) function c_init()
   end function
 
   subroutine sub(d)
     type(u), value :: d
   end subroutine
 end program test_pr58586
-
diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 
b/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03
index 4a55d73b245e..9ff38e3fb7c5 100644
--- a/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03
+++ b/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03
@@ -51,14 +51,14 @@ contains
     type(t), value :: d
   end subroutine
 
-  type(c) function c_init() ! { dg-warning "not set" }
+  type(c) function c_init()
   end function
 
   class(c) function c_init2() ! { dg-warning "not set" }
     allocatable :: c_init2
   end function
 
-  type(c) function d_init(this) ! { dg-warning "not set" }
+  type(c) function d_init(this)
     class(d) :: this
   end function
 
@@ -102,4 +102,3 @@ program test_pr58586
   call add_c(oe%init())
   deallocate(oe)
 end program
-
diff --git a/gcc/testsuite/gfortran.dg/allocate_with_source_14.f03 
b/gcc/testsuite/gfortran.dg/allocate_with_source_14.f03
index fd2db7439fe0..36c1245ccdd8 100644
--- a/gcc/testsuite/gfortran.dg/allocate_with_source_14.f03
+++ b/gcc/testsuite/gfortran.dg/allocate_with_source_14.f03
@@ -210,5 +210,5 @@ program main
   call v%free()
   deallocate(av)
 end program
-! { dg-final { scan-tree-dump-times "__builtin_malloc" 22 "original" } }
+! { dg-final { scan-tree-dump-times "__builtin_malloc" 23 "original" } }
 ! { dg-final { scan-tree-dump-times "__builtin_free" 29 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/derived_constructor_comps_6.f90 
b/gcc/testsuite/gfortran.dg/derived_constructor_comps_6.f90
index bdfa47b1df53..406e031456ff 100644
--- a/gcc/testsuite/gfortran.dg/derived_constructor_comps_6.f90
+++ b/gcc/testsuite/gfortran.dg/derived_constructor_comps_6.f90
@@ -129,5 +129,5 @@ contains
     prt_spec = name
   end function new_prt_spec3
 end program main
-! { dg-final { scan-tree-dump-times "__builtin_malloc" 15 "original" } }
+! { dg-final { scan-tree-dump-times "__builtin_malloc" 16 "original" } }
 ! { dg-final { scan-tree-dump-times "__builtin_free" 33 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/derived_result_5.f90 
b/gcc/testsuite/gfortran.dg/derived_result_5.f90
new file mode 100644
index 000000000000..1ba4d19dc449
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/derived_result_5.f90
@@ -0,0 +1,123 @@
+! { dg-do run }
+! { dg-additional-options "-O2 -Wreturn-type" }
+!
+! PR fortran/85750 - default-initialization and functions returning derived 
type
+
+module bar
+  implicit none
+  type ilist
+    integer          :: count = 42
+    integer, pointer :: ptr(:) => null()
+  end type ilist
+
+  type jlist
+    real, allocatable :: a(:)
+    integer           :: count = 23
+  end type jlist
+
+contains
+
+  function make_list(i)
+    integer,     intent(in)   :: i
+    type(ilist), dimension(2) :: make_list
+    make_list(i)%count = i
+  end function make_list
+
+  function make_list_res(i) result(list)
+    integer,     intent(in)   :: i
+    type(ilist), dimension(2) :: list
+    list(i)%count = i
+  end function make_list_res
+
+  function make_jlist(i)
+    integer,     intent(in)   :: i
+    type(jlist), dimension(2) :: make_jlist
+    make_jlist(i)%count = i
+  end function make_jlist
+
+  function make_jlist_res(i) result(list)
+    integer,     intent(in)   :: i
+    type(jlist), dimension(2) :: list
+    list(i)%count = i
+  end function make_jlist_res
+
+  function empty_ilist()
+    type(ilist), dimension(2) :: empty_ilist
+  end function
+
+  function empty_jlist()
+    type(jlist), dimension(2) :: empty_jlist
+  end function
+
+  function empty_ilist_res() result (res)
+    type(ilist), dimension(2) :: res
+  end function
+
+  function empty_jlist_res() result (res)
+    type(jlist), dimension(2) :: res
+  end function
+
+end module bar
+
+program foo
+  use bar
+  implicit none
+  type(ilist)              :: mylist(2) = ilist(count=-2)
+  type(jlist), allocatable :: yourlist(:)
+
+  mylist = ilist(count=-1)
+  if (any (mylist%count /= [-1,-1])) stop 1
+  mylist = empty_ilist()
+  if (any (mylist%count /= [42,42])) stop 2
+  mylist = ilist(count=-1)
+  mylist = empty_ilist_res()
+  if (any (mylist%count /= [42,42])) stop 3
+
+  allocate(yourlist(1:2))
+  if (any (yourlist%count /= [23,23])) stop 4
+  yourlist = jlist(count=-1)
+  if (any (yourlist%count /= [-1,-1])) stop 5
+  yourlist = empty_jlist()
+  if (any (yourlist%count /= [23,23])) stop 6
+  yourlist = jlist(count=-1)
+  yourlist = empty_jlist_res()
+  if (any (yourlist%count /= [23,23])) stop 7
+
+  mylist = make_list(1)
+  if (any (mylist%count /= [1,42])) stop 11
+  mylist = make_list(2)
+  if (any (mylist%count /= [42,2])) stop 12
+  mylist = (make_list(1))
+  if (any (mylist%count /= [1,42])) stop 13
+  mylist = [make_list(2)]
+  if (any (mylist%count /= [42,2])) stop 14
+
+  mylist = make_list_res(1)
+  if (any (mylist%count /= [1,42])) stop 21
+  mylist = make_list_res(2)
+  if (any (mylist%count /= [42,2])) stop 22
+  mylist = (make_list_res(1))
+  if (any (mylist%count /= [1,42])) stop 23
+  mylist = [make_list_res(2)]
+  if (any (mylist%count /= [42,2])) stop 24
+
+  yourlist = make_jlist(1)
+  if (any (yourlist%count /= [1,23])) stop 31
+  yourlist = make_jlist(2)
+  if (any (yourlist%count /= [23,2])) stop 32
+  yourlist = (make_jlist(1))
+  if (any (yourlist%count /= [1,23])) stop 33
+  yourlist = [make_jlist(2)]
+  if (any (yourlist%count /= [23,2])) stop 34
+
+  yourlist = make_jlist_res(1)
+  if (any (yourlist%count /= [1,23])) stop 41
+  yourlist = make_jlist_res(2)
+  if (any (yourlist%count /= [23,2])) stop 42
+  yourlist = (make_jlist_res(1))
+  if (any (yourlist%count /= [1,23])) stop 43
+  yourlist = [make_jlist_res(2)]
+  if (any (yourlist%count /= [23,2])) stop 44
+
+  deallocate (yourlist)
+end program foo

Reply via email to