From: Steve Baird <ba...@adacore.com> Update GNAT RM documentation of the Size'Class aspect.
gcc/ada/ChangeLog: * doc/gnat_rm/gnat_language_extensions.rst: Update documentation for mutably tagged types and the Size'Class aspect. * gnat_rm.texi: Regenerate. Tested on x86_64-pc-linux-gnu, committed on master. --- .../doc/gnat_rm/gnat_language_extensions.rst | 183 +++++++++------- gcc/ada/gnat_rm.texi | 198 +++++++++++------- 2 files changed, 229 insertions(+), 152 deletions(-) diff --git a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst index 0a08a83a5a2..bdc4e675488 100644 --- a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst +++ b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst @@ -1350,113 +1350,150 @@ case statement with composite selector type". Mutably Tagged Types with Size'Class Aspect ------------------------------------------- -The ``Size'Class`` aspect can be applied to a tagged type to specify a size -constraint for the type and its descendants. When this aspect is specified -on a tagged type, the class-wide type of that type is considered to be a -"mutably tagged" type - meaning that objects of the class-wide type can have -their tag changed by assignment from objects with a different tag. +For a specific tagged nonformal type T that satisfies some conditions +described later in this section, the universal-integer-valued type-related +representation aspect ``Size'Class`` may be specified; any such specified +aspect value shall be static. + +Specifying this aspect imposes an upper bound on the sizes of all specific +descendants of T (including T itself). T'Class (but not T) is then said to be +a "mutably tagged" type - meaning that T'Class is a definite subtype and that +the tag of a variable of type T'Class may be modified by assignment in some +cases described later in this section. An inherited ``Size'Class`` aspect +value may be overridden, but not with a larger value. + +If the ``Size'Class`` aspect is specified for a type T, then every specific +descendant of T (including T itself) + +* shall have a Size that does not exceed the specified value; and + +* shall have a (possibly inherited) ``Size'Class`` aspect that does not exceed + the specifed value; and + +* shall be undiscriminated; and + +* shall have no composite subcomponent whose subtype is subject to a nonstatic + constraint; and + +* shall not have a tagged partial view other than a private extension; and + +* shall not be a descendant of an interface type; and + +* shall not have a statically deeper accessibility level than that of T. + +If the ``Size'Class`` aspect is not specified for a type T (either explicitly +or by inheritance), then it shall not be specified for any descendant of T. Example: .. code-block:: ada - type Base is tagged null record - with Size'Class => 16 * 8; -- Size in bits (128 bits, or 16 bytes) + type Root_Type is tagged null record with Size'Class => 16 * 8; - type Derived_Type is new Base with record - Data_Field : Integer; + type Derived_Type is new Root_Type with record + Stuff : Some_Type; end record; -- ERROR if Derived_Type exceeds 16 bytes -Class-wide types with a specified ``Size'Class`` can be used as the type of -array components, record components, and stand-alone objects. +Because any subtype of a mutably tagged type is definite, it can be used as a +component subtype for enclosing array or record types, as the subtype of a +default-initialized stand-alone object, or as the subtype of an uninitialized +allocator, as in this example: .. code-block:: ada - Inst : Base'Class; - type Array_of_Base is array (Positive range <>) of Base'Class; + Obj : Root_Type'Class; + type Array_of_Roots is array (Positive range <>) of Root_Type'Class; -If the ``Size'Class`` aspect is specified for a type ``T``, then every -specific descendant of ``T`` [redundant: (including ``T``)] +Default initialization of an object of such a definite subtype proceeds as +for the corresponding specific type, except that Program_Error is raised if +the specific type is abstract. In particular, the initial tag of the object +is that of the corresponding specific type. -- shall have a Size that does not exceed the specified value; and +There is a general design principle that if a type has a tagged partial view, +then the type's ``Size'Class`` aspect (or lack thereof) should be determinable +by looking only at the partial view. That provides the motivation for the +rules of the next two paragraphs. -- shall be undiscriminated; and +If a type has a tagged partial view, then a ``Size'Class`` aspect specification +may be provided only at the point of the partial view declaration (in other +words, no such aspect specification may be provided when the full view of +the type is declared). All of the above rules (in particular, the rule that +an overriding ``Size'Class`` aspect value shall not be larger than the +overridden inherited value) are also enforced when the full view (which may +have a different ancestor type than that of the partial view) is declared. +If a partial view for a type inherits a ``Size'Class`` aspect value and does +not override that value with an explicit aspect specification, then the +(static) aspect values inherited by the partial view and by the full view +shall be equal. -- shall have no composite subcomponent whose subtype is subject to a - dynamic constraint; and +An actual parameter of an instantiation whose corresponding formal parameter +is a formal tagged private type shall not be either mutably tagged or the +corresponding specific type of a mutably tagged type. -- shall have no interface progenitors; and +For the legality rules in this section, the RM 12.3(11) rule about legality +checking in the visible part and formal part of an instance is extended (in +the same way that it is extended in many other places in the RM) to include +the private part of an instance. -- shall not have a tagged partial view other than a private extension; and +An object (or a view thereof) of a tagged type is defined to be +"tag-constrained" if it is -- shall not have a statically deeper accessibility level than that of ``T``. +* an object whose type is not mutably tagged; or -In addition to the places where Legality Rules normally apply (see 12.3), -these legality rules apply also in the private part and in the body of an -instance of a generic unit. +* a constant object; or -For any subtype ``S`` that is a subtype of a descendant of ``T``, ``S'Class'Size`` is -defined to yield the specified value [redundant:, although ``S'Class'Size`` is -not a static expression]. +* a view conversion of a tag-constrained object; or -A class-wide descendant of a type with a specified ``Size'Class`` aspect is -defined to be a "mutably tagged" type. Any subtype of a mutably tagged type is, -by definition, a definite subtype (RM 3.3 notwithstanding). Default -initialization of an object of such a definite subtype proceeds as for the -corresponding specific type, except that ``Program_Error`` is raised if the -specific type is abstract. [In particular, the initial tag of the object is -that of the corresponding specific type.] +* a view conversion to a type that is not a descendant of the operand's + type; or -An object of a tagged type is defined to be "tag-constrained" if it is +* a formal in out or out parameter whose corresponding actual parameter is + tag-constrained; or -- an object whose type is not mutably tagged; or +* a dereference of an access value. -- a constant object; or - -- a view conversion of a tag-constrained object; or - -- a formal ``in out`` or ``out`` parameter whose corresponding - actual parameter is tag-constrained. - -In the case of an assignment to a tagged variable that -is not tag-constrained, no check is performed that the tag of the value of -the expression is the same as that of the target (RM 5.2 notwithstanding). +In the case of an assignment to a tagged variable that is not +tag-constrained, no check is performed that the tag of the value +of the expression is the same as that of the target (RM 5.2 notwithstanding). Instead, the tag of the target object becomes that of the source object of -the assignment. +the assignment. Note that the tag of an object of a mutably tagged type MT +will always be the tag of some specific type that is a descendant of MT. An assignment to a composite object similarly copies the tags of any -subcomponents of the source object that have a mutably-tagged type. +subcomponents of the source object that have a mutably tagged type. -The ``Constrained`` attribute is defined for any name denoting an object of a -mutably tagged type (RM 3.7.2 notwithstanding). In this case, the Constrained -attribute yields the value True if the object is tag-constrained and False -otherwise. +The Constrained attribute is defined for any name denoting an object of a +mutably tagged type (RM 3.7.2 notwithstanding). In this case, the +Constrained attribute yields the value True if the object is +tag-constrained and False otherwise. -Renaming is not allowed (see 8.5.1) for a type conversion having an operand of -a mutably tagged type ``MT`` and a target type ``TT`` such that ``TT'Class`` -does not cover ``MT``, nor for any part of such an object, nor for any slice -of such an object. This rule also applies in any context where a name is -required to be one for which "renaming is allowed" (for example, see RM 12.4). +Renaming is not allowed (see RM 8.5.1) for a type conversion having an operand +of a mutably tagged type MT and a target type TT such that TT (or its +corresponding specific type if TT is class-wide) is not an ancestor of MT +(this is sometimes called a "downward" conversion), nor for any part of +such an object, nor for any slice of any part of such an object. This +rule also applies in any context where a name is required to be one for +which "renaming is allowed" (for example, see RM 12.4). +[This is analogous to the way that renaming is not allowed for a +discriminant-dependent component of an unconstrained variable.] -A name denoting a view of a variable of a mutably tagged type shall not -occur as an operative constituent of the prefix of a name denoting a -prefixed view of a callable entity, except as the callee name in a call to -the callable entity. - -For a type conversion between two general access types, either both or neither -of the designated types shall be mutably tagged. For an ``Access`` (or -``Unchecked_Access``) attribute reference, the designated type of the type of the -attribute reference and the type of the prefix of the attribute shall either -both or neither be mutably tagged. +A name denoting a view of a variable of a mutably tagged type shall not occur +as an operative constituent of the prefix of a name denoting a prefixed +view of a callable entity, except as the callee name in a call to the +callable entity. This disallows, for example, renaming such a prefixed view, +passing the prefixed view name as a generic actual parameter, or using the +prefixed view name as the prefix of an attribute. The execution of a construct is erroneous if the construct has a constituent that is a name denoting a subcomponent of a tagged object and the object's -tag is changed by this execution between evaluating the name and the last use -(within this execution) of the subcomponent denoted by the name. +tag is changed by this execution between evaluating the name and the last +use (within this execution) of the subcomponent denoted by the name. +This is analogous to the RM 3.7.2(4) rule about discriminant-dependent +subcomponents. -If the type of a formal parameter is a specific tagged type then the execution +If the type of a formal parameter is a specific tagged type, then the execution of the call is erroneous if the tag of the actual is changed while the formal -parameter exists (that is, before leaving the corresponding callable -construct). +parameter exists (that is, before leaving the corresponding callable construct). +This is analogous to the RM 6.4.1(18) rule about discriminated parameters. Generalized Finalization ------------------------ diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 0ae1a24dc82..f0264d75668 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -19,7 +19,7 @@ @copying @quotation -GNAT Reference Manual , Jun 02, 2025 +GNAT Reference Manual , Jun 27, 2025 AdaCore @@ -30799,77 +30799,107 @@ case statement with composite selector type”. @subsection Mutably Tagged Types with Size’Class Aspect -The @code{Size'Class} aspect can be applied to a tagged type to specify a size -constraint for the type and its descendants. When this aspect is specified -on a tagged type, the class-wide type of that type is considered to be a -“mutably tagged” type - meaning that objects of the class-wide type can have -their tag changed by assignment from objects with a different tag. +For a specific tagged nonformal type T that satisfies some conditions +described later in this section, the universal-integer-valued type-related +representation aspect @code{Size'Class} may be specified; any such specified +aspect value shall be static. -Example: +Specifying this aspect imposes an upper bound on the sizes of all specific +descendants of T (including T itself). T’Class (but not T) is then said to be +a “mutably tagged” type - meaning that T’Class is a definite subtype and that +the tag of a variable of type T’Class may be modified by assignment in some +cases described later in this section. An inherited @code{Size'Class} aspect +value may be overridden, but not with a larger value. -@example -type Base is tagged null record - with Size'Class => 16 * 8; -- Size in bits (128 bits, or 16 bytes) - -type Derived_Type is new Base with record - Data_Field : Integer; -end record; -- ERROR if Derived_Type exceeds 16 bytes -@end example - -Class-wide types with a specified @code{Size'Class} can be used as the type of -array components, record components, and stand-alone objects. - -@example -Inst : Base'Class; -type Array_of_Base is array (Positive range <>) of Base'Class; -@end example - -If the @code{Size'Class} aspect is specified for a type @code{T}, then every -specific descendant of @code{T} [redundant: (including @code{T})] +If the @code{Size'Class} aspect is specified for a type T, then every specific +descendant of T (including T itself) -@itemize - +@itemize * @item shall have a Size that does not exceed the specified value; and +@item +shall have a (possibly inherited) @code{Size'Class} aspect that does not exceed +the specifed value; and + @item shall be undiscriminated; and @item -shall have no composite subcomponent whose subtype is subject to a -dynamic constraint; and - -@item -shall have no interface progenitors; and +shall have no composite subcomponent whose subtype is subject to a nonstatic +constraint; and @item shall not have a tagged partial view other than a private extension; and @item -shall not have a statically deeper accessibility level than that of @code{T}. +shall not be a descendant of an interface type; and + +@item +shall not have a statically deeper accessibility level than that of T. @end itemize -In addition to the places where Legality Rules normally apply (see 12.3), -these legality rules apply also in the private part and in the body of an -instance of a generic unit. +If the @code{Size'Class} aspect is not specified for a type T (either explicitly +or by inheritance), then it shall not be specified for any descendant of T. -For any subtype @code{S} that is a subtype of a descendant of @code{T}, @code{S'Class'Size} is -defined to yield the specified value [redundant:, although @code{S'Class'Size} is -not a static expression]. +Example: -A class-wide descendant of a type with a specified @code{Size'Class} aspect is -defined to be a “mutably tagged” type. Any subtype of a mutably tagged type is, -by definition, a definite subtype (RM 3.3 notwithstanding). Default -initialization of an object of such a definite subtype proceeds as for the -corresponding specific type, except that @code{Program_Error} is raised if the -specific type is abstract. [In particular, the initial tag of the object is -that of the corresponding specific type.] +@example +type Root_Type is tagged null record with Size'Class => 16 * 8; -An object of a tagged type is defined to be “tag-constrained” if it is +type Derived_Type is new Root_Type with record + Stuff : Some_Type; +end record; -- ERROR if Derived_Type exceeds 16 bytes +@end example + +Because any subtype of a mutably tagged type is definite, it can be used as a +component subtype for enclosing array or record types, as the subtype of a +default-initialized stand-alone object, or as the subtype of an uninitialized +allocator, as in this example: + +@example +Obj : Root_Type'Class; +type Array_of_Roots is array (Positive range <>) of Root_Type'Class; +@end example + +Default initialization of an object of such a definite subtype proceeds as +for the corresponding specific type, except that Program_Error is raised if +the specific type is abstract. In particular, the initial tag of the object +is that of the corresponding specific type. + +There is a general design principle that if a type has a tagged partial view, +then the type’s @code{Size'Class} aspect (or lack thereof) should be determinable +by looking only at the partial view. That provides the motivation for the +rules of the next two paragraphs. + +If a type has a tagged partial view, then a @code{Size'Class} aspect specification +may be provided only at the point of the partial view declaration (in other +words, no such aspect specification may be provided when the full view of +the type is declared). All of the above rules (in particular, the rule that +an overriding @code{Size'Class} aspect value shall not be larger than the +overridden inherited value) are also enforced when the full view (which may +have a different ancestor type than that of the partial view) is declared. +If a partial view for a type inherits a @code{Size'Class} aspect value and does +not override that value with an explicit aspect specification, then the +(static) aspect values inherited by the partial view and by the full view +shall be equal. + +An actual parameter of an instantiation whose corresponding formal parameter +is a formal tagged private type shall not be either mutably tagged or the +corresponding specific type of a mutably tagged type. + +For the legality rules in this section, the RM 12.3(11) rule about legality +checking in the visible part and formal part of an instance is extended (in +the same way that it is extended in many other places in the RM) to include +the private part of an instance. + +An object (or a view thereof) of a tagged type is defined to be +“tag-constrained” if it is -@itemize - +@itemize * @item an object whose type is not mutably tagged; or @@ -30881,49 +30911,59 @@ a constant object; or a view conversion of a tag-constrained object; or @item -a formal @code{in out} or @code{out} parameter whose corresponding -actual parameter is tag-constrained. +a view conversion to a type that is not a descendant of the operand’s +type; or + +@item +a formal in out or out parameter whose corresponding actual parameter is +tag-constrained; or + +@item +a dereference of an access value. @end itemize -In the case of an assignment to a tagged variable that -is not tag-constrained, no check is performed that the tag of the value of -the expression is the same as that of the target (RM 5.2 notwithstanding). +In the case of an assignment to a tagged variable that is not +tag-constrained, no check is performed that the tag of the value +of the expression is the same as that of the target (RM 5.2 notwithstanding). Instead, the tag of the target object becomes that of the source object of -the assignment. +the assignment. Note that the tag of an object of a mutably tagged type MT +will always be the tag of some specific type that is a descendant of MT. An assignment to a composite object similarly copies the tags of any -subcomponents of the source object that have a mutably-tagged type. +subcomponents of the source object that have a mutably tagged type. -The @code{Constrained} attribute is defined for any name denoting an object of a -mutably tagged type (RM 3.7.2 notwithstanding). In this case, the Constrained -attribute yields the value True if the object is tag-constrained and False -otherwise. +The Constrained attribute is defined for any name denoting an object of a +mutably tagged type (RM 3.7.2 notwithstanding). In this case, the +Constrained attribute yields the value True if the object is +tag-constrained and False otherwise. -Renaming is not allowed (see 8.5.1) for a type conversion having an operand of -a mutably tagged type @code{MT} and a target type @code{TT} such that @code{TT'Class} -does not cover @code{MT}, nor for any part of such an object, nor for any slice -of such an object. This rule also applies in any context where a name is -required to be one for which “renaming is allowed” (for example, see RM 12.4). +Renaming is not allowed (see RM 8.5.1) for a type conversion having an operand +of a mutably tagged type MT and a target type TT such that TT (or its +corresponding specific type if TT is class-wide) is not an ancestor of MT +(this is sometimes called a “downward” conversion), nor for any part of +such an object, nor for any slice of any part of such an object. This +rule also applies in any context where a name is required to be one for +which “renaming is allowed” (for example, see RM 12.4). +[This is analogous to the way that renaming is not allowed for a +discriminant-dependent component of an unconstrained variable.] -A name denoting a view of a variable of a mutably tagged type shall not -occur as an operative constituent of the prefix of a name denoting a -prefixed view of a callable entity, except as the callee name in a call to -the callable entity. - -For a type conversion between two general access types, either both or neither -of the designated types shall be mutably tagged. For an @code{Access} (or -@code{Unchecked_Access}) attribute reference, the designated type of the type of the -attribute reference and the type of the prefix of the attribute shall either -both or neither be mutably tagged. +A name denoting a view of a variable of a mutably tagged type shall not occur +as an operative constituent of the prefix of a name denoting a prefixed +view of a callable entity, except as the callee name in a call to the +callable entity. This disallows, for example, renaming such a prefixed view, +passing the prefixed view name as a generic actual parameter, or using the +prefixed view name as the prefix of an attribute. The execution of a construct is erroneous if the construct has a constituent that is a name denoting a subcomponent of a tagged object and the object’s -tag is changed by this execution between evaluating the name and the last use -(within this execution) of the subcomponent denoted by the name. +tag is changed by this execution between evaluating the name and the last +use (within this execution) of the subcomponent denoted by the name. +This is analogous to the RM 3.7.2(4) rule about discriminant-dependent +subcomponents. -If the type of a formal parameter is a specific tagged type then the execution +If the type of a formal parameter is a specific tagged type, then the execution of the call is erroneous if the tag of the actual is changed while the formal -parameter exists (that is, before leaving the corresponding callable -construct). +parameter exists (that is, before leaving the corresponding callable construct). +This is analogous to the RM 6.4.1(18) rule about discriminated parameters. @node Generalized Finalization,No_Raise aspect,Mutably Tagged Types with Size’Class Aspect,Experimental Language Extensions @anchor{gnat_rm/gnat_language_extensions generalized-finalization}@anchor{465} -- 2.43.0