[all-commits] [llvm/llvm-project] 996c0f: [flang] Avoid cycles during instantiation of deriv...

Roger Ferrer Ibáñez via All-commits all-commits at lists.llvm.org
Thu Sep 21 05:41:09 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 996c0fb3a2c28047d19b6a151f6f357c5022c137
      https://github.com/llvm/llvm-project/commit/996c0fb3a2c28047d19b6a151f6f357c5022c137
  Author: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
  Date:   2023-09-21 (Thu, 21 Sep 2023)

  Changed paths:
    M flang/lib/Semantics/resolve-names.cpp
    A flang/test/Semantics/typeinfo05.f90
    A flang/test/Semantics/typeinfo06.f90

  Log Message:
  -----------
  [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 https://github.com/llvm/llvm-project/issues/64973

Differential Revision: https://reviews.llvm.org/D159117




More information about the All-commits mailing list