17.3.6 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.

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

Class-wide types with a specified Size'Class can be used as the type of array components, record components, and stand-alone objects.

Inst : Base'Class;
type Array_of_Base is array (Positive range <>) of Base'Class;

If the Size'Class aspect is specified for a type T, then every specific descendant of T [redundant: (including T)]

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.

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 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.]

An object of a tagged type is defined to be “tag-constrained” if it is

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. An assignment to a composite object similarly copies the tags of any 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.

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).

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.

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.

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).