aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2025-01-11 08:23:48 +0000
committerPaul Thomas <pault@gcc.gnu.org>2025-01-11 08:23:48 +0000
commitd64ca15351029164bac30b49fb3c4f9723e755de (patch)
treec21dac1b0ebce75755c5456451df1c7f23b57e74
parent664bd76a23def2d458bb3c531486b4c220f29c11 (diff)
downloadgcc-d64ca15351029164bac30b49fb3c4f9723e755de.zip
gcc-d64ca15351029164bac30b49fb3c4f9723e755de.tar.gz
gcc-d64ca15351029164bac30b49fb3c4f9723e755de.tar.bz2
Fortran: Fix error recovery for bad component arrayspecs [PR108434]
2025-01-11 Paul Thomas <pault@gcc.gnu.org> gcc/fortran/ PR fortran/108434 * class.cc (generate_finalization_wrapper): To avoid memory leaks from callocs, return immediately if the derived type error flag is set. * decl.cc (build_struct): If the declaration of a derived type or class component does not have a deferred arrayspec, correct, set the error flag of the derived type and emit an immediate error. gcc/testsuite/ PR fortran/108434 * gfortran.dg/pr108434.f90 : Add tests from comment 1.
-rw-r--r--gcc/fortran/class.cc2
-rw-r--r--gcc/fortran/decl.cc19
-rw-r--r--gcc/testsuite/gfortran.dg/pr108434.f9010
3 files changed, 26 insertions, 5 deletions
diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 3e0dce1..97ff54d 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -1739,7 +1739,7 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
gfc_expr *ancestor_wrapper = NULL, *rank;
gfc_iterator *iter;
- if (derived->attr.unlimited_polymorphic)
+ if (derived->attr.unlimited_polymorphic || derived->error)
{
vtab_final->initializer = gfc_get_null_expr (NULL);
return;
diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index 1bc86ae..0c59760 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -2421,11 +2421,24 @@ build_struct (const char *name, gfc_charlen *cl, gfc_expr **init,
}
else if (c->attr.allocatable)
{
+ const char *err = G_("Allocatable component of structure at %C must have "
+ "a deferred shape");
if (c->as->type != AS_DEFERRED)
{
- gfc_error ("Allocatable component of structure at %C must have a "
- "deferred shape");
- return false;
+ if (c->ts.type == BT_CLASS || c->ts.type == BT_DERIVED)
+ {
+ /* Issue an immediate error and allow this component to pass for
+ the sake of clean error recovery. Set the error flag for the
+ containing derived type so that finalizers are not built. */
+ gfc_error_now (err);
+ s->sym->error = 1;
+ c->as->type = AS_DEFERRED;
+ }
+ else
+ {
+ gfc_error (err);
+ return false;
+ }
}
}
else
diff --git a/gcc/testsuite/gfortran.dg/pr108434.f90 b/gcc/testsuite/gfortran.dg/pr108434.f90
index e1768a5..b7f4353 100644
--- a/gcc/testsuite/gfortran.dg/pr108434.f90
+++ b/gcc/testsuite/gfortran.dg/pr108434.f90
@@ -1,11 +1,19 @@
! { dg-do compile }
! PR fortran/108434 - ICE in class_allocatable
-! Contributed by G.Steinmetz
+! Contributed by G.Steinmetz <gscfq@t-online.de>
program p
type t
class(c), pointer :: a(2) ! { dg-error "must have a deferred shape" }
end type t
+ type s
+ class(d), allocatable :: a(2) ! { dg-error "must have a deferred shape|not been declared" }
+ end type
+ type u
+ type(e), allocatable :: b(2) ! { dg-error "must have a deferred shape|not been declared" }
+ end type
class(t), allocatable :: x
class(t), pointer :: y
+ class(s), allocatable :: x2
+ class(s), pointer :: y2
end