Dear all,

here's a couple of NULL pointer dereferences on invalid code.

Regtested on x86_64-pc-linux-gnu.

OK for master?

Thanks,
Harald


PR fortran/95980 - ICE on using sync images with -fcheck=bounds

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.

diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index db5174f3f21..7d3711c55f9 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -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);
     }
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index f3e8ffc204c..4574e8cd752 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -9224,7 +9224,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
index 00000000000..7c8260a96e0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr95980.f90
@@ -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

Reply via email to