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)
Size'Class aspect that does not exceed
the specifed value; and
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:
type Root_Type is tagged null record with Size'Class => 16 * 8; type Derived_Type is new Root_Type with record Stuff : Some_Type; end record; -- ERROR if Derived_Type exceeds 16 bytes
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:
Obj : Root_Type'Class; type Array_of_Roots is array (Positive range <>) of Root_Type'Class;
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 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 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.
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
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. 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.
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 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. 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. 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 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). This is analogous to the RM 6.4.1(18) rule about discriminated parameters.