public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-8235] fortran: Detect duplicate unlimited polymorphic types [PR103662]
@ 2022-04-24 13:32 Mikael Morin
  0 siblings, 0 replies; only message in thread
From: Mikael Morin @ 2022-04-24 13:32 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:fa5cd7102da676dcb1757b1288421f5f3439ae0e

commit r12-8235-gfa5cd7102da676dcb1757b1288421f5f3439ae0e
Author: Mikael Morin <mikael@gcc.gnu.org>
Date:   Sun Apr 24 15:05:41 2022 +0200

    fortran: Detect duplicate unlimited polymorphic types [PR103662]
    
    This fixes a type-based alias analysis issue with unlimited polymorphic
    class descriptors (types behind class(*)) causing data initialisation to
    be removed by optimization.
    
    The fortran front-end may create multiple declarations for types, for
    example if a type is redeclared in each program unit it is used in.
    To avoid optimization seeing them as non-aliasing, a list of derived
    types is created at resolution time, and used at translation to set
    the same TYPE_CANONICAL type for each duplicate type declaration.
    
    This mechanism didn’t work for unlimited polymorphic descriptors types,
    as there is a short-circuit return skipping all the resolution handling
    for them, including the type registration.
    
    This change adds type registration at the short-circuit return, and
    updates type comparison to handle specifically unlimited polymorphic
    fake symbols, class descriptor types and virtual table types.
    
    The test, which exhibited mismatching dynamic types had to be fixed as
    well.
    
            PR fortran/103662
    
    gcc/fortran/ChangeLog:
    
            * interface.cc (gfc_compare_derived_types): Support comparing
            unlimited polymorphic fake symbols.  Recursively compare class
            descriptor types and virtual table types.
            * resolve.cc (resolve_fl_derived): Add type to the types list
            on unlimited polymorphic short-circuit return.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/unlimited_polymorphic_3.f03 (foo): Separate
            bind(c) and sequence checks to...
            (foo_bc, foo_sq): ... two different procedures.
            (main, foo*): Change type declarations so that type name,
            component name, and either bind(c) or sequence attribute match
            between the main type declarations and the procedure type
            declarations.
            (toplevel): Add optimization dump checks.
    
    Co-Authored-By: Jakub Jelinek <jakub@redhat.com>

Diff:
---
 gcc/fortran/interface.cc                           | 19 ++++++--
 gcc/fortran/resolve.cc                             |  5 +-
 .../gfortran.dg/unlimited_polymorphic_3.f03        | 56 +++++++++++++++-------
 3 files changed, 58 insertions(+), 22 deletions(-)

diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index 000a530cba4..7ed6e13711f 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -618,6 +618,14 @@ gfc_compare_derived_types (gfc_symbol *derived1, gfc_symbol *derived2)
   if (!derived1 || !derived2)
     gfc_internal_error ("gfc_compare_derived_types: invalid derived type");
 
+  if (derived1->attr.unlimited_polymorphic
+      && derived2->attr.unlimited_polymorphic)
+    return true;
+
+  if (derived1->attr.unlimited_polymorphic
+      != derived2->attr.unlimited_polymorphic)
+    return false;
+
   /* Compare UNION types specially.  */
   if (derived1->attr.flavor == FL_UNION || derived2->attr.flavor == FL_UNION)
     return compare_union_types (derived1, derived2);
@@ -630,10 +638,11 @@ gfc_compare_derived_types (gfc_symbol *derived1, gfc_symbol *derived2)
       && strcmp (derived1->module, derived2->module) == 0)
     return true;
 
-  /* Compare type via the rules of the standard.  Both types must have
-     the SEQUENCE or BIND(C) attribute to be equal. STRUCTUREs are special
-     because they can be anonymous; therefore two structures with different
-     names may be equal.  */
+  /* Compare type via the rules of the standard.  Both types must have the
+     SEQUENCE or BIND(C) attribute to be equal.  We also compare types
+     recursively if they are class descriptors types or virtual tables types.
+     STRUCTUREs are special because they can be anonymous; therefore two
+     structures with different names may be equal.  */
 
   /* Compare names, but not for anonymous types such as UNION or MAP.  */
   if (!is_anonymous_dt (derived1) && !is_anonymous_dt (derived2)
@@ -646,6 +655,8 @@ gfc_compare_derived_types (gfc_symbol *derived1, gfc_symbol *derived2)
 
   if (!(derived1->attr.sequence && derived2->attr.sequence)
       && !(derived1->attr.is_bind_c && derived2->attr.is_bind_c)
+      && !(derived1->attr.is_class && derived2->attr.is_class)
+      && !(derived1->attr.vtype && derived2->attr.vtype)
       && !(derived1->attr.pdt_type && derived2->attr.pdt_type))
     return false;
 
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 05f8f1bf6c2..29df531cdb6 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -15151,7 +15151,10 @@ resolve_fl_derived (gfc_symbol *sym)
 
       /* Nothing more to do for unlimited polymorphic entities.  */
       if (data->ts.u.derived->attr.unlimited_polymorphic)
-	return true;
+	{
+	  add_dt_to_dt_list (sym);
+	  return true;
+	}
       else if (vptr->ts.u.derived == NULL)
 	{
 	  gfc_symbol *vtab = gfc_find_derived_vtab (data->ts.u.derived);
diff --git a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03 b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03
index 075d6d727e2..780d68cdd87 100644
--- a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03
+++ b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03
@@ -1,4 +1,5 @@
 ! { dg-do run }
+! { dg-additional-options "-fdump-tree-dse-details" }
 !
 ! Check that pointer assignments allowed by F2003:C717
 ! work and check null initialization of CLASS(*) pointers.
@@ -7,20 +8,31 @@
 !
 program main
   interface
-    subroutine foo(z)
+    subroutine foo_bc(z)
       class(*), pointer, intent(in) :: z
-    end subroutine foo
+    end subroutine foo_bc
+    subroutine foo_sq(z)
+      class(*), pointer, intent(in) :: z
+    end subroutine foo_sq
   end interface
+  type, bind(c) :: bc
+    integer :: i
+  end type bc
   type sq
     sequence
-    integer :: i
+    integer :: k
   end type sq
+  type(bc), target :: w
   type(sq), target :: x
   class(*), pointer :: y, z
-  x%i = 42
+  w%i = 23
+  y => w
+  z => y ! unlimited => unlimited allowed
+  call foo_bc(z)
+  x%k = 42
   y => x
   z => y ! unlimited => unlimited allowed
-  call foo (z)
+  call foo_sq(z)
   call bar
 contains
   subroutine bar
@@ -33,21 +45,31 @@ contains
 
 end program main
 
-
-subroutine foo(tgt)
+subroutine foo_bc(tgt)
   use iso_c_binding
   class(*), pointer, intent(in) :: tgt
-  type, bind(c) :: s
-    integer (c_int) :: k
-  end type s
-  type t
+  type, bind(c) :: bc
+    integer (c_int) :: i
+  end type bc
+  type(bc), pointer :: ptr1
+  ptr1 => tgt ! bind(c) => unlimited allowed
+  if (ptr1%i .ne. 23) STOP 2
+end subroutine foo_bc
+
+subroutine foo_sq(tgt)
+  class(*), pointer, intent(in) :: tgt
+  type sq
     sequence
     integer :: k
-  end type t
-  type(s), pointer :: ptr1
-  type(t), pointer :: ptr2
-  ptr1 => tgt ! bind(c) => unlimited allowed
-  if (ptr1%k .ne. 42) STOP 2
+  end type sq
+  type(sq), pointer :: ptr2
   ptr2 => tgt ! sequence type => unlimited allowed
   if (ptr2%k .ne. 42) STOP 3
-end subroutine foo
+end subroutine foo_sq
+
+! PR fortran/103662
+! We used to produce multiple independant types for the unlimited polymorphic
+! descriptors (types for class(*)) which caused stores to them to be seen as
+! useless.
+! { dg-final { scan-tree-dump-not "Deleted dead store: z._data = &w" "dse1" } }
+! { dg-final { scan-tree-dump-not "Deleted dead store: z._data = &x" "dse1" } }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-04-24 13:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-24 13:32 [gcc r12-8235] fortran: Detect duplicate unlimited polymorphic types [PR103662] Mikael Morin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).