PR fortran/95980 - ICE on using sync images with -fcheck=bounds
authorHarald Anlauf <anlauf@gmx.de>
Mon, 6 Jul 2020 16:58:23 +0000 (18:58 +0200)
committerHarald Anlauf <anlauf@gmx.de>
Mon, 6 Jul 2020 17:00:10 +0000 (19:00 +0200)
In SELECT TYPE, the argument may be an incorrectly specified unlimited
polymorphic variable.  Avoid a NULL pointer dereference for clean error
recovery.

gcc/fortran/
PR fortran/95980
* match.c (copy_ts_from_selector_to_associate, build_class_sym):
Distinguish between unlimited polymorphic and ordinary variables
to avoid NULL pointer dereference.
* resolve.c (resolve_select_type):
Distinguish between unlimited polymorphic and ordinary variables
to avoid NULL pointer dereference.

gcc/fortran/match.c
gcc/fortran/resolve.c
gcc/testsuite/gfortran.dg/pr95980.f90 [new file with mode: 0644]

index db5174f3f211cd8624f02ae83fe154df132d2b24..7d3711c55f9857854e3c1254793c09106af5b967 100644 (file)
@@ -6159,14 +6159,18 @@ copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector)
   while (ref && ref->next)
     ref = ref->next;
 
-  if (selector->ts.type == BT_CLASS && CLASS_DATA (selector)->as
+  if (selector->ts.type == BT_CLASS
+      && CLASS_DATA (selector)
+      && CLASS_DATA (selector)->as
       && CLASS_DATA (selector)->as->type == AS_ASSUMED_RANK)
     {
       assoc_sym->attr.dimension = 1;
       assoc_sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
       goto build_class_sym;
     }
-  else if (selector->ts.type == BT_CLASS && CLASS_DATA (selector)->as
+  else if (selector->ts.type == BT_CLASS
+          && CLASS_DATA (selector)
+          && CLASS_DATA (selector)->as
           && ref && ref->type == REF_ARRAY)
     {
       /* Ensure that the array reference type is set.  We cannot use
@@ -6223,7 +6227,8 @@ build_class_sym:
     {
       /* The correct class container has to be available.  */
       assoc_sym->ts.type = BT_CLASS;
-      assoc_sym->ts.u.derived = CLASS_DATA (selector)->ts.u.derived;
+      assoc_sym->ts.u.derived = CLASS_DATA (selector)
+       ? CLASS_DATA (selector)->ts.u.derived : selector->ts.u.derived;
       assoc_sym->attr.pointer = 1;
       gfc_build_class_symbol (&assoc_sym->ts, &assoc_sym->attr, &assoc_sym->as);
     }
index e8ba48770f7982facc4c004407033bf09288a8c1..223dcccce9114a2dde15f96361c755e239351781 100644 (file)
@@ -9241,7 +9241,8 @@ 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;
-         selector_type = CLASS_DATA (code->expr2)->ts.u.derived;
+         selector_type = CLASS_DATA (code->expr2)
+           ? CLASS_DATA (code->expr2)->ts.u.derived : code->expr2->ts.u.derived;
        }
 
       if (code->expr2->rank && CLASS_DATA (code->expr1)->as)
diff --git a/gcc/testsuite/gfortran.dg/pr95980.f90 b/gcc/testsuite/gfortran.dg/pr95980.f90
new file mode 100644 (file)
index 0000000..7c8260a
--- /dev/null
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! PR fortran/95980 - ICE in get_unique_type_string, at fortran/class.c:485
+
+program p
+  type t
+  end type t
+  class(t) :: x        ! { dg-error "must be dummy, allocatable or pointer" }
+  select type (y => x)
+  end select
+end