aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorAndre Vehreschild <vehre@gcc.gnu.org>2024-08-23 16:28:38 +0200
committerAndre Vehreschild <vehre@gcc.gnu.org>2024-09-19 12:17:08 +0200
commitde915fbe3cb1ce7be35dce7d6bc8d04dc7125e61 (patch)
treede666afa3abf4ed2d8bbc90c4576c371da58eea7 /gcc/fortran
parent427f82425855fbcd2991578f3b83672b7512efbd (diff)
downloadgcc-de915fbe3cb1ce7be35dce7d6bc8d04dc7125e61.zip
gcc-de915fbe3cb1ce7be35dce7d6bc8d04dc7125e61.tar.gz
gcc-de915fbe3cb1ce7be35dce7d6bc8d04dc7125e61.tar.bz2
Fortran: Break recursion building recursive types. [PR106606]
Build a derived type component's type only, when it is not already being built and the component uses pointer semantics. gcc/fortran/ChangeLog: PR fortran/106606 * trans-types.cc (gfc_get_derived_type): Only build non-pointer derived types as component's types when they are not yet built. gcc/testsuite/ChangeLog: * gfortran.dg/recursive_alloc_comp_5.f90: New test.
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/trans-types.cc20
1 files changed, 14 insertions, 6 deletions
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 3a1ff98..96ef8b4 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2905,18 +2905,26 @@ gfc_get_derived_type (gfc_symbol * derived, int codimen)
will be built and so we can return the type. */
for (c = derived->components; c; c = c->next)
{
- bool same_alloc_type = c->attr.allocatable
- && derived == c->ts.u.derived;
-
if (c->ts.type == BT_UNION && c->ts.u.derived->backend_decl == NULL)
c->ts.u.derived->backend_decl = gfc_get_union_type (c->ts.u.derived);
if (c->ts.type != BT_DERIVED && c->ts.type != BT_CLASS)
continue;
- if ((!c->attr.pointer && !c->attr.proc_pointer
- && !same_alloc_type)
- || c->ts.u.derived->backend_decl == NULL)
+ const bool incomplete_type
+ = c->ts.u.derived->backend_decl
+ && TREE_CODE (c->ts.u.derived->backend_decl) == RECORD_TYPE
+ && !(TYPE_LANG_SPECIFIC (c->ts.u.derived->backend_decl)
+ && TYPE_LANG_SPECIFIC (c->ts.u.derived->backend_decl)->size);
+ const bool pointer_component
+ = c->attr.pointer || c->attr.allocatable || c->attr.proc_pointer;
+
+ /* Prevent endless recursion on recursive types (i.e. types that reference
+ themself in a component. Break the recursion by not building pointers
+ to incomplete types again, aka types that are already in the build. */
+ if (c->ts.u.derived->backend_decl == NULL
+ || (c->attr.codimension && c->as->corank != codimen)
+ || !(incomplete_type && pointer_component))
{
int local_codim = c->attr.codimension ? c->as->corank: codimen;
c->ts.u.derived->backend_decl = gfc_get_derived_type (c->ts.u.derived,