]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fortran: Fix a problem with SELECT TYPE selectors [PR104555].
authorPaul Thomas <pault@gcc.gnu.org>
Mon, 30 Oct 2023 07:12:40 +0000 (07:12 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Mon, 30 Oct 2023 07:12:40 +0000 (07:12 +0000)
2023-10-30  Paul Thomas  <pault@gcc.gnu.org>

gcc/fortran
PR fortran/104555
* resolve.cc (resolve_select_type): If the selector expression
has no class component references and the expression is a
derived type, copy the typespec of the symbol to that of the
expression.

gcc/testsuite/
PR fortran/104555
* gfortran.dg/pr104555.f90: New test.

gcc/fortran/resolve.cc
gcc/testsuite/gfortran.dg/pr104555.f90 [new file with mode: 0644]

index 9f4dc0726457e584a0590ecabf87e4de099b95c6..81a14653a0440fc6babede6c266f06c2af69b4ca 100644 (file)
@@ -9578,6 +9578,12 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
        {
          if (code->expr1->symtree->n.sym->attr.untyped)
            code->expr1->symtree->n.sym->ts = code->expr2->ts;
+         /* Sometimes the selector expression is given the typespec of the
+            '_data' field, which is logical enough but inappropriate here. */
+         if (code->expr2->ts.type == BT_DERIVED
+             && code->expr2->symtree
+             && code->expr2->symtree->n.sym->ts.type == BT_CLASS)
+           code->expr2->ts = code->expr2->symtree->n.sym->ts;
          selector_type = CLASS_DATA (code->expr2)
            ? CLASS_DATA (code->expr2)->ts.u.derived : code->expr2->ts.u.derived;
        }
diff --git a/gcc/testsuite/gfortran.dg/pr104555.f90 b/gcc/testsuite/gfortran.dg/pr104555.f90
new file mode 100644 (file)
index 0000000..1fc5b5b
--- /dev/null
@@ -0,0 +1,32 @@
+! { dg-do compile }
+!
+! Test the fix for PR104555 in which the select type statement caused an
+! ICE because the selector expression was type(t) rather than class(t).
+!
+! Contributed by Gerhard Steinmetz  <gscfq@t-online.de>
+!
+program p
+   type t
+      character(:), allocatable :: a
+   end type
+   call s(t("abcd"))
+   call s([t("efgh")])
+contains
+   subroutine s(x)
+      class(t) :: x(..)
+      select rank (x)
+      rank (0)
+         print *, "|", x%a, "|"
+         select type (y => x)
+         type is (t)
+           print *, "|", y%a, "|"
+         end select
+      rank (1)
+         print *, "|", x(1)%a, "|"
+         select type (y => x)
+         type is (t)
+           print *, "|", y(1)%a, "|"
+         end select
+      end select
+   end
+end