Hi All,

This was a rather vexatious bug to track down and squash. I was led astray
by the appearance of the bug in the tests for the implementation of
intrinsic transformational functions with class arguments. It turns out to
be an incipient bug in the handling of character(*) array associate names
that is fixed by provision of an appropriate DECL_EXPR.

Note that I have not attempted to fix the apparent regression
in tree-ssanames.cc, which occurred sometime between gcc-12.2.1 and
gcc-12.4.1. Once this patch is pushed, I will convert the PR accordingly.

Furthermore, PR101760(fortran) and PRs 96114/117145(C). I'll turn to the
former, once the dust has settled on the regressions that I have caused in
recent weeks.

The patch regression tests fine. OK for mainline?

Paul

Attachment: Change.Logs
Description: Binary data

diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index 80a9502a8a4..ae3266fb867 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -2065,6 +2065,20 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
 		  || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
       gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));

+      if (sym->ts.type == BT_CHARACTER)
+	{
+	  /* Emit a DECL_EXPR for the variable sized array type in so the
+	     gimplification of its type sizes works correctly.  */
+	  tree arraytype;
+	  tmp = TREE_TYPE (sym->backend_decl);
+	  arraytype = TREE_TYPE (GFC_TYPE_ARRAY_DATAPTR_TYPE (tmp));
+	  if (! TYPE_NAME (arraytype))
+	    TYPE_NAME (arraytype) = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
+						NULL_TREE, arraytype);
+	  gfc_add_expr_to_block (&se.pre, build1 (DECL_EXPR,
+				 arraytype, TYPE_NAME (arraytype)));
+	}
+
       if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
 	{
 	  if (INDIRECT_REF_P (se.expr))
diff --git a/gcc/testsuite/gfortran.dg/class_transformational_1.f90 b/gcc/testsuite/gfortran.dg/class_transformational_1.f90
index 3e64f5d91e5..77ec24a43c0 100644
--- a/gcc/testsuite/gfortran.dg/class_transformational_1.f90
+++ b/gcc/testsuite/gfortran.dg/class_transformational_1.f90
@@ -169,7 +169,7 @@ contains
   end

   subroutine unlimited_rebar (arg)
-    class(*), allocatable :: arg(:)              ! Not having this allocatable => pr117901
+    class(*) :: arg(:)
     call class_bar (arg)
   end

diff --git a/gcc/testsuite/gfortran.dg/pr117901.f90 b/gcc/testsuite/gfortran.dg/pr117901.f90
new file mode 100644
index 00000000000..b5c3a4fc277
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr117901.f90
@@ -0,0 +1,30 @@
+! { dg-do compile }
+! { dg-options "-O3" }
+!
+! Test the fix for pr117901, in which the variable length character in
+! the SELECT TYPE construct caused an ICE in make_ssa_name_fn. This is
+! a much reduced testcase, extracted from class_transformational_1.f90.
+! Note that it does not have references to transformational functions
+! of class objects!
+!
+Module class_tests
+contains
+  subroutine class_rebar (arg)
+    class(*), allocatable :: arg(:)
+    call class_bar (arg)
+  end
+  subroutine class_bar(x)
+    class(*), intent(in) :: x(..)
+    integer :: checksum
+    select rank (x)
+      rank (1)
+        select type (x)
+          type is (character(*))
+            checksum = sum(ichar(x(:)(1:1)) + ichar(x(:)(2:2)))
+            print *, checksum
+        end select
+      rank (2)
+      rank (3)
+      end select
+  end
+end module class_tests

Reply via email to