Example of illegal code:

```ada
package P is
   type T is tagged null record;
   procedure Proc (X : T);
   type U is new T with null record;
   procedure Proc (X : U);
end P;

package body P is
   procedure Proc (X : T) is null;
   procedure Proc (X : U) is null;
end P;
```

This error is issued on tagged type extensions like type `U` which extends
type `T`. Such a declaration violates legality rule 8 of [section 7.7 of SPARK
Reference Manual]. While static elaboration checking prevents statically calling
`Proc` before its body has been elaborated (i.e. all its dependencies have been
initialized), `Proc` might still be called dynamically before that point,
through a dispatching call whose controlling operand (`this` or `self` object
in other languages) has static type `T'Class` and dynamic type `U`.

In order to ensure that no such call can occur between the declaration of type
extension `U` and the corresponding overriding body of `Proc`, pragma
`Elaborate_Body` should be used at the beginning of package `P` as follows:

```ada
package P is
   pragma Elaborate_Body;
   type T is tagged null record;
   ...
```

That way, the spec and body of package `P` are elaborated in sequence, which
prevents here any call to `Proc` between the declaration of `U` and the body of
`Proc`.

[section 7.7 of SPARK Reference Manual]:
https://docs.adacore.com/live/wave/spark2014/html/spark2014_rm/packages.html#elaboration-issues
