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

Reply via email to