Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[flang] Avoid cycles during instantiation of derived types
Derived-type-spec (such as `type(t)`) typically cause the instantiation of a class which is also used to define the offsets of its data components and the size of the class. Fortran derived types are always "completely" defined (i.e., no incomplete / opaque derived types exist on which we can build a pointer to them like in C/C++) so they can have their offsets always computed. However, we must be careful not to instantiate a derived type while it is being defined. This can happen due to cycles introduced by forward references, such as the one below. ```lang=fortran type t1 type(t2), pointer :: b ! (A) end type t1 type :: t2 ! (B) type(t1), pointer :: a ! (C) end type t2 ! (D) ``` At `(A)`, flang determines that this is a forward declaration so no instantiation happens. At `(B)`, flang determines `t2` is not a forward declaration anymore, because we are defining it. At `(C)`, flang chooses to instantiate `t1`. Instantiation of `t1` finds the field `b` at `(A)`. Now `t2` is not a forward declaration anymore, so it can be instantiated. But at this point the field `a` has not been added to `t2`, so we compute the size of an empty class. Because this computation is done just once, we end emitting a wrong derived type descriptor with a `sizeinbytes` field set to 0. Because these kind of cycles can only happen via forward referenced derived types specifiers, the idea here is to avoid instantiating the derived type being defined (i.e. `t2`) until `(D)`. Keeping the attribute "is forward reference" set until `(D)` avoids that. Fixes #64973 Differential Revision: https://reviews.llvm.org/D159117
- Loading branch information