public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r10-10393] Fortran: avoid several NULL pointer dereferences during error recovery
@ 2022-01-13 21:32 Harald Anlauf
  0 siblings, 0 replies; only message in thread
From: Harald Anlauf @ 2022-01-13 21:32 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:7bfdbb657919b5049e459e02d130056cfe3777b6

commit r10-10393-g7bfdbb657919b5049e459e02d130056cfe3777b6
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Mon Dec 27 23:06:18 2021 +0100

    Fortran: avoid several NULL pointer dereferences during error recovery
    
    gcc/fortran/ChangeLog:
    
            PR fortran/102332
            * expr.c (gfc_get_variable_expr): Avoid NULL pointer dereferences
            during handling of errors with invalid uses of CLASS variables.
            * match.c (select_type_set_tmp): Likewise.
            * primary.c (gfc_match_varspec): Likewise.
            * resolve.c (resolve_variable): Likewise.
            (resolve_select_type): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            PR fortran/102332
            * gfortran.dg/pr102332.f90: New test.
    
    (cherry picked from commit d8f6c48ccb85ecc0d97a84c32b7a1b8f43c64fe4)

Diff:
---
 gcc/fortran/expr.c                     |  3 +-
 gcc/fortran/match.c                    |  3 +-
 gcc/fortran/primary.c                  |  1 +
 gcc/fortran/resolve.c                  |  9 ++++-
 gcc/testsuite/gfortran.dg/pr102332.f90 | 69 ++++++++++++++++++++++++++++++++++
 5 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 95b35153941..e8c7c212e70 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -5149,7 +5149,8 @@ gfc_get_variable_expr (gfc_symtree *var)
 
   if (var->n.sym->attr.flavor != FL_PROCEDURE
       && ((var->n.sym->as != NULL && var->n.sym->ts.type != BT_CLASS)
-	   || (var->n.sym->ts.type == BT_CLASS && CLASS_DATA (var->n.sym)
+	   || (var->n.sym->ts.type == BT_CLASS && var->n.sym->ts.u.derived
+	       && CLASS_DATA (var->n.sym)
 	       && CLASS_DATA (var->n.sym)->as)))
     {
       e->rank = var->n.sym->ts.type == BT_CLASS
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index ef6c86af2f9..7d06e0eef30 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -6338,7 +6338,8 @@ select_type_set_tmp (gfc_typespec *ts)
       sym = tmp->n.sym;
       gfc_add_type (sym, ts, NULL);
 
-      if (selector->ts.type == BT_CLASS && selector->attr.class_ok)
+      if (selector->ts.type == BT_CLASS && selector->attr.class_ok
+	  && selector->ts.u.derived && CLASS_DATA (selector))
 	{
 	  sym->attr.pointer
 		= CLASS_DATA (selector)->attr.class_pointer;
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index b03961a9981..78c4b634db3 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -2172,6 +2172,7 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
 	  && !(gfc_matching_procptr_assignment
 	       && sym->attr.flavor == FL_PROCEDURE))
       || (sym->ts.type == BT_CLASS && sym->attr.class_ok
+	  && sym->ts.u.derived && CLASS_DATA (sym)
 	  && (CLASS_DATA (sym)->attr.dimension
 	      || CLASS_DATA (sym)->attr.codimension)))
     {
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 591b36fa4bd..9104b17988b 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -5677,6 +5677,8 @@ resolve_variable (gfc_expr *e)
      can't be translated that way.  */
   if (sym->assoc && e->rank == 0 && e->ref && sym->ts.type == BT_CLASS
       && sym->assoc->target && sym->assoc->target->ts.type == BT_CLASS
+      && sym->assoc->target->ts.u.derived
+      && CLASS_DATA (sym->assoc->target)
       && CLASS_DATA (sym->assoc->target)->as)
     {
       gfc_ref *ref = e->ref;
@@ -5741,7 +5743,8 @@ resolve_variable (gfc_expr *e)
   /* Like above, but for class types, where the checking whether an array
      ref is present is more complicated.  Furthermore make sure not to add
      the full array ref to _vptr or _len refs.  */
-  if (sym->assoc && sym->ts.type == BT_CLASS
+  if (sym->assoc && sym->ts.type == BT_CLASS && sym->ts.u.derived
+      && CLASS_DATA (sym)
       && CLASS_DATA (sym)->attr.dimension
       && (e->ts.type != BT_DERIVED || !e->ts.u.derived->attr.vtype))
     {
@@ -9345,6 +9348,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
 
       /* Check F03:C815.  */
       if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
+	  && selector_type
 	  && !selector_type->attr.unlimited_polymorphic
 	  && !gfc_type_is_extensible (c->ts.u.derived))
 	{
@@ -9355,7 +9359,8 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
 	}
 
       /* Check F03:C816.  */
-      if (c->ts.type != BT_UNKNOWN && !selector_type->attr.unlimited_polymorphic
+      if (c->ts.type != BT_UNKNOWN
+	  && selector_type && !selector_type->attr.unlimited_polymorphic
 	  && ((c->ts.type != BT_DERIVED && c->ts.type != BT_CLASS)
 	      || !gfc_type_is_extension_of (selector_type, c->ts.u.derived)))
 	{
diff --git a/gcc/testsuite/gfortran.dg/pr102332.f90 b/gcc/testsuite/gfortran.dg/pr102332.f90
new file mode 100644
index 00000000000..f9557094083
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr102332.f90
@@ -0,0 +1,69 @@
+! { dg-do compile }
+! PR fortran/102332 - ICE in select_type_set_tmp
+! Contributed by G.Steinmetz
+
+program p
+  type t
+     real :: a, b
+  end type
+  class(t), allocatable :: x ! Valid
+  select type (y => x)
+  type is (t)
+     y%a = 0
+  end select
+end
+
+subroutine s0 (x)
+  type t
+     real :: a, b
+  end type
+  class(t) :: x ! Valid
+  select type (y => x)
+  type is (t)
+     y%a = 0
+  end select
+end
+
+subroutine s1
+  type t
+     real :: a, b
+  end type
+  class(t) :: x         ! { dg-error "must be dummy, allocatable or pointer" }
+  select type (y => x)
+  type is (t)
+     y%a = 0
+  end select
+end
+
+subroutine s3
+  type t
+     real :: a, b
+  end type
+  class(t) :: x         ! { dg-error "must be dummy, allocatable or pointer" }
+  select type (y => x)
+  class is (t)
+     y%a = 0
+  end select
+end
+
+subroutine s2
+  type t
+     real :: a, b
+  end type
+  class(t) :: x         ! { dg-error "must be dummy, allocatable or pointer" }
+  select type (y => x)
+  type default          ! { dg-error "Expected" }
+     y%a = 0
+  end select
+end
+
+subroutine s4
+  type t
+     real :: a, b
+  end type
+  class(t) :: x         ! { dg-error "must be dummy, allocatable or pointer" }
+  select type (y => x)
+  class default
+     y%a = 0
+  end select
+end


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-01-13 21:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-13 21:32 [gcc r10-10393] Fortran: avoid several NULL pointer dereferences during error recovery Harald Anlauf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).