PR fortran/95980 - ICE in get_unique_type_string, at fortran/class.c:485

Message ID trinity-6d315391-ab74-4082-92cb-8bfda893314b-1593464317998@3c-app-gmx-bap46
State New
Headers show
Series
  • PR fortran/95980 - ICE in get_unique_type_string, at fortran/class.c:485
Related show

Commit Message

Harald Anlauf June 29, 2020, 8:58 p.m.
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.

Comments

Harald Anlauf July 5, 2020, 8:36 p.m. | #1
Early ping.

> Gesendet: Montag, 29. Juni 2020 um 22:58 Uhr

> Von: "Harald Anlauf" <anlauf@gmx.de>

> An: "fortran" <fortran@gcc.gnu.org>, "gcc-patches" <gcc-patches@gcc.gnu.org>

> Betreff: [PATCH] PR fortran/95980 - ICE in get_unique_type_string, at fortran/class.c:485

>

> 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.
Thomas Koenig July 6, 2020, 6:40 a.m. | #2
Hi Harald,

> Early ping.


OK. Thanks for the patch!

Regards

	Thomas

Patch

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