https://gcc.gnu.org/g:3e97c4c02be61e185b513788dfe493a565147997
commit r16-8438-g3e97c4c02be61e185b513788dfe493a565147997 Author: Tonu Naks <[email protected]> Date: Fri Apr 3 09:44:18 2026 +0200 Ada: Update documentation to reflect relaxed structural instantiation gcc/ada/ * doc/gnat_rm/gnat_language_extensions.rst: Adjust rules for structural generic instantiations. * gnat_rm.texi: Regenerate. Diff: --- gcc/ada/doc/gnat_rm/gnat_language_extensions.rst | 51 +++++++++++++++++++--- gcc/ada/gnat_rm.texi | 54 +++++++++++++++++++++--- 2 files changed, 92 insertions(+), 13 deletions(-) diff --git a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst index a30df54170a3..cd5391e6f69d 100644 --- a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst +++ b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst @@ -1888,16 +1888,25 @@ The generic unit shall not take a generic formal object of mode ``in out``. If the generic unit takes a generic formal object of mode ``in``, then the corresponding generic actual parameter shall be a static expression. -A ``structural_generic_instance_name`` shall not be present in a library -unit if the structural instance is also a library unit and has a semantic -dependence on the former. +A ``structural_generic_instance_name`` for a generic package shall not be +present in a library unit if the structural instance is also a library unit +and has a semantic dependence on the former. + +For a generic subprogram, if a local entity of the enclosing library-level +package is used as an actual and the structural instance would have a semantic +dependence on the package, the structural instantiation is automatically +demoted to a local instantiation. In this case, several instances of the +generic subprogram may be present in a single partition, unless +whole-partition optimization is performed (e.g., via LTO). Static Semantics ^^^^^^^^^^^^^^^^ A ``structural_generic_instance_name`` denotes the instance that is the product of the structural instantiation of a generic unit on the specified -actual parameters. This instance is unique to a partition. +actual parameters. This instance is unique to a partition, except when a +generic subprogram instantiation is automatically demoted to a local +instantiation as described under Legality Rules. Example: @@ -1937,8 +1946,9 @@ Note that the following example is illegal: The reason is that ``Ada.Containers.Vectors``, ``Positive`` and ``Q.T`` being library-level entities, the structural instance ``Ada.Containers.Vectors(Positive,T)`` is a library unit with a dependence -on ``Q`` and, therefore, cannot be referenced from within ``Q``. The simple -way out is to declare a traditional instantiation in this case: +on ``Q`` and, therefore, cannot be referenced from within ``Q``. This +restriction applies to structural instantiations of generic packages. The +simple way out is to declare a traditional instantiation in this case: .. code-block:: ada @@ -1971,6 +1981,35 @@ But the following example is legal: because the structural instance ``Ada.Containers.Vectors(Positive,T)`` is not a library unit. +For generic subprograms, the restriction does not apply: if a local entity of +a library-level package is used as an actual, the structural instantiation is +automatically demoted to a local instantiation. For example: + +.. code-block:: ada + + with Ada.Unchecked_Deallocation; + + package Q is + type T is record + I : Integer; + end record; + + type T_Access is access T; + end Q; + + package body Q is + procedure Free_T (X : in out T_Access) is + begin + Ada.Unchecked_Deallocation(T, T_Access)(X); + end Free_T; + end Q; + +is legal: since ``T`` and ``T_Access`` are local entities of ``Q``, the +structural instantiation of ``Ada.Unchecked_Deallocation`` is demoted to a +local instantiation rather than producing an error. Note that the uniqueness +guarantee no longer holds in this case and several instances of the generic +subprogram may be present in a single partition. + The first example can be rewritten in a less verbose manner: .. code-block:: ada diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 468206219d4b..74c8f747b49c 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -33014,9 +33014,16 @@ The generic unit shall not take a generic formal object of mode @code{in out}. If the generic unit takes a generic formal object of mode @code{in}, then the corresponding generic actual parameter shall be a static expression. -A @code{structural_generic_instance_name} shall not be present in a library -unit if the structural instance is also a library unit and has a semantic -dependence on the former. +A @code{structural_generic_instance_name} for a generic package shall not be +present in a library unit if the structural instance is also a library unit +and has a semantic dependence on the former. + +For a generic subprogram, if a local entity of the enclosing library-level +package is used as an actual and the structural instance would have a semantic +dependence on the package, the structural instantiation is automatically +demoted to a local instantiation. In this case, several instances of the +generic subprogram may be present in a single partition, unless +whole-partition optimization is performed (e.g., via LTO). @node Static Semantics,,Legality Rules<3>,Structural Generic Instantiation @anchor{gnat_rm/gnat_language_extensions static-semantics}@anchor{47d} @@ -33025,7 +33032,10 @@ dependence on the former. A @code{structural_generic_instance_name} denotes the instance that is the product of the structural instantiation of a generic unit on the specified -actual parameters. This instance is unique to a partition. +actual parameters. This instance is unique to a partition, except when a +generic subprogram instantiation is automatically demoted to a local +instantiation as described under Legality Rules. + Example: @@ -33063,9 +33073,10 @@ package Q is end Q; @end example -The reason is that @code{Ada.Containers.Vectors}, @code{Positive} and @code{Q.T} being -library-level entities, the structural instance @code{Ada.Containers.Vectors(Positive,T)} is a library unit with a dependence -on @code{Q} and, therefore, cannot be referenced from within @code{Q}. The simple +The reason is that @code{Ada.Containers.Vectors}, @code{Positive} and @code{Q.T} +being library-level entities, the structural instance @code{Ada.Containers.Vectors(Positive,T)} is a library unit with a dependence +on @code{Q} and, therefore, cannot be referenced from within @code{Q}. This +restriction applies to structural instantiations of generic packages. The simple way out is to declare a traditional instantiation in this case: @example @@ -33099,6 +33110,35 @@ end; because the structural instance @code{Ada.Containers.Vectors(Positive,T)} is not a library unit. +For generic subprograms, the restriction does not apply: if a local entity of +a library-level package is used as an actual, the structural instantiation is +automatically demoted to a local instantiation. For example: + +@example +with Ada.Unchecked_Deallocation; + +package Q is + type T is record + I : Integer; + end record; + + type T_Access is access T; +end Q; + +package body Q is + procedure Free_T (X : in out T_Access) is + begin + Ada.Unchecked_Deallocation(T, T_Access)(X); + end Free_T; +end Q; +@end example + +is legal: since @code{T} and @code{T_Access} are local entities of @code{Q}, +the structural instantiation of @code{Ada.Unchecked_Deallocation} is demoted +to a local instantiation rather than producing an error. Note that the +uniqueness guarantee no longer holds in this case and several instances of +the generic subprogram may be present in a single partition. + The first example can be rewritten in a less verbose manner: @example
