dwww Home | Show directory contents | Find package


                         13   Representation Issues


1/3 {8652/0009} {AI95-00137-01} {AI05-0299-1} [This clause describes features
for querying and controlling certain aspects of entities and for interfacing
to hardware.]


                         Wording Changes from Ada 83

1.a/3       {AI05-0299-1} The subclauses of this clause have been reorganized.
            This was necessary to preserve a logical order, given the new Ada
            95 semantics given in this section.


13.1 Operational and Representation Aspects


0.1/3 {8652/0009} {AI95-00137-01} {AI05-0295-1} [Two kinds of aspects of
entities can be specified: representation aspects and operational aspects.
Representation aspects affect how the types and other entities of the language
are to be mapped onto the underlying machine. Operational aspects determine
other properties of entities.]

0.2/3 {AI05-0183-1} {AI05-0295-1} [Either kind of aspect of an entity may be
specified by means of an aspect_specification (see 13.1.1), which is an
optional element of most kinds of declarations and applies to the entity or
entities being declared. Aspects may also be specified by certain other
constructs occurring subsequent to the declaration of the affected entity: a
representation aspect value may be specified by means of a representation item
and an operational aspect value may be specified by means of an operational
item.]

1/1 {8652/0009} {AI95-00137-01} There are six kinds of representation items:
attribute_definition_clauses for representation attributes, enumeration_-
representation_clauses, record_representation_clauses, at_clauses,
component_clauses, and representation pragmas. [ They can be provided to give
more efficient representation or to interface with features that are outside
the domain of the language (for example, peripheral hardware). ]

1.1/1 {8652/0009} {AI95-00137-01} An operational item is an
attribute_definition_clause for an operational attribute.

1.2/1 {8652/0009} {AI95-00137-01} [An operational item or a representation
item applies to an entity identified by a local_name, which denotes an entity
declared local to the current declarative region, or a library unit declared
immediately preceding a representation pragma in a compilation.]


                         Language Design Principles

1.a/3       {8652/0009} {AI95-00137-01} {AI05-0295-1} Representation aspects
            are intended to refer to properties that need to be known before
            the compiler can generate code to create or access an entity. For
            instance, the size of an object needs to be known before the
            object can be created. Conversely, operational aspects are those
            that only need to be known before they can be used. For instance,
            how an object is read from a stream only needs to be known when a
            stream read is executed. Thus, representation aspects have
            stricter rules as to when they can be specified.

1.a.1/3     {AI95-00291-02} {AI05-0295-1} Confirming the value of an aspect
            should never change the semantics of the aspect. Thus Size = 8
            (for example) means the same thing whether it was specified with a
            representation item or whether the compiler chose this value by
            default.

1.a.2/3     Glossary entry: An aspect is a specifiable property of an entity.
            An aspect may be specified by an aspect_specification on the
            declaration of the entity. Some aspects may be queried via
            attributes.


                                   Syntax

2/1     {8652/0009} {AI95-00137-01} aspect_clause ::= 
        attribute_definition_clause
              | enumeration_representation_clause
              | record_representation_clause
              | at_clause

3       local_name ::= direct_name
              | direct_name'attribute_designator
              | library_unit_name

4/1     {8652/0009} {AI95-00137-01} A representation pragma is allowed only at
        places where an aspect_clause or compilation_unit is allowed.


                            Name Resolution Rules

5/1 {8652/0009} {AI95-00137-01} In an operational item or representation item,
if the local_name is a direct_name, then it shall resolve to denote a
declaration (or, in the case of a pragma, one or more declarations) that
occurs immediately within the same declarative region as the item. If the
local_name has an attribute_designator, then it shall resolve to denote an
implementation-defined component (see 13.5.1) or a class-wide type implicitly
declared immediately within the same declarative region as the item. A
local_name that is a library_unit_name (only permitted in a representation
pragma) shall resolve to denote the library_item that immediately precedes
(except for other pragmas) the representation pragma.

5.a/1       Reason: {8652/0009} {AI95-00137-01} This is a
            Name Resolution Rule, because we don't want an operational or
            representation item for X to be ambiguous just because there's
            another X declared in an outer declarative region. It doesn't make
            much difference, since most operational or representation items
            are for types or subtypes, and type and subtype names can't be
            overloaded.

5.b/1       Ramification: {8652/0009} {AI95-00137-01} The visibility rules
            imply that the declaration has to occur before the operational or
            representation item.

5.c/1       {8652/0009} {AI95-00137-01} For objects, this implies that
            operational or representation items can be applied only to
            stand-alone objects.


                               Legality Rules

6/1 {8652/0009} {AI95-00137-01} The local_name of an aspect_clause or
representation pragma shall statically denote an entity (or, in the case of a
pragma, one or more entities) declared immediately preceding it in a
compilation, or within the same declarative_part, package_specification, task_-
definition, protected_definition, or record_definition as the representation
or operational item. If a local_name denotes a [local] callable entity, it may
do so through a [local] subprogram_renaming_declaration [(as a way to resolve
ambiguity in the presence of overloading)]; otherwise, the local_name shall
not denote a renaming_declaration.

6.a         Ramification: The "statically denote" part implies that it is
            impossible to specify the representation of an object that is not
            a stand-alone object, except in the case of a representation item
            like pragma Atomic that is allowed inside a component_list (in
            which case the representation item specifies the representation of
            components of all objects of the type). It also prevents the
            problem of renamings of things like "P.all" (where P is an
            access-to-subprogram value) or "E(I)" (where E is an entry family).

6.b         The part about where the denoted entity has to have been declared
            appears twice - once as a Name Resolution Rule, and once as a
            Legality Rule. Suppose P renames Q, and we have a representation
            item in a declarative_part whose local_name is P. The fact that
            the representation item has to appear in the same
            declarative_part as P is a Name Resolution Rule, whereas the fact
            that the representation item has to appear in the same
            declarative_part as Q is a Legality Rule. This is subtle, but it
            seems like the least confusing set of rules.

6.c         Discussion: A separate Legality Rule applies for
            component_clauses. See 13.5.1, "Record Representation Clauses".

7/2 {AI95-00291-02} The representation of an object consists of a certain
number of bits (the size of the object). For an object of an elementary type,
these are the bits that are normally read or updated by the machine code when
loading, storing, or operating-on the value of the object. For an object of a
composite type, these are the bits reserved for this object, and include bits
occupied by subcomponents of the object. If the size of an object is greater
than that of its subtype, the additional bits are padding bits. For an
elementary object, these padding bits are normally read and updated along with
the others. For a composite object, padding bits might not be read or updated
in any given composite operation, depending on the implementation.

7.a/2       To be honest: {AI95-00291-02} Discontiguous representations are
            allowed, but the ones we're interested in here are generally
            contiguous sequences of bits. For a discontiguous representation,
            the size doesn't necessarily describe the "footprint" of the
            object in memory (that is, the amount of space taken in the
            address space for the object).

7.a.1/2     Discussion: {AI95-00291-02} In the case of composite objects, we
            want the implementation to have the flexibility to either do
            operations component-by-component, or with a block operation
            covering all of the bits. We carefully avoid giving a preference
            in the wording. There is no requirement for the choice to be
            documented, either, as the implementation can make that choice
            based on many factors, and could make a different choice for
            different operations on the same object.

7.a.2/2     {AI95-00291-02} In the case of a properly aligned, contiguous
            object whose size is a multiple of the storage unit size, no other
            bits should be read or updated as part of operating on the object.
            We don't say this normatively because it would be difficult to
            normatively define "properly aligned" or "contiguous".

7.b         Ramification: Two objects with the same value do not necessarily
            have the same representation. For example, an implementation might
            represent False as zero and True as any odd value. Similarly, two
            objects (of the same type) with the same sequence of bits do not
            necessarily have the same value. For example, an implementation
            might use a biased representation in some cases but not others:

7.c/3           {AI05-0229-1} subtype S is Integer range 1..256;
                type A is array(Natural range 1..4) of S
                   with Pack;
                X : S := 3;
                Y : A := (1, 2, 3, 4);

7.d         The implementation might use a biased-by-1 representation for the
            array elements, but not for X. X and Y(3) have the same value, but
            different representation: the representation of X is a sequence of
            (say) 32 bits: 0...011, whereas the representation of Y(3) is a
            sequence of 8 bits: 00000010 (assuming a two's complement
            representation).

7.e         Such tricks are not required, but are allowed.

7.f         Discussion: The value of any padding bits is not specified by the
            language, though for a numeric type, it will be much harder to
            properly implement the predefined operations if the padding bits
            are not either all zero, or a sign extension.

7.g/3       Ramification: {AI05-0229-1} For example, suppose S'Size = 2, and
            an object X is of subtype S. If the machine code typically uses a
            32-bit load instruction to load the value of X, then X'Size should
            be 32, even though 30 bits of the value are just zeros or
            sign-extension bits. On the other hand, if the machine code
            typically masks out those 30 bits, then X'Size should be 2.
            Usually, such masking only happens for components of a composite
            type for which Pack, Component_Size, or record layout is specified.

7.h         Note, however, that the formal parameter of an instance of
            Unchecked_Conversion is a special case. Its Size is required to be
            the same as that of its subtype.

7.i         Note that we don't generally talk about the representation of a
            value. A value is considered to be an amorphous blob without any
            particular representation. An object is considered to be more
            concrete.

8/3 {AI05-0112-1} {AI05-0295-1} A representation item directly specifies a
representation aspect of the entity denoted by the local_name, except in the
case of a type-related representation item, whose local_name shall denote a
first subtype, and which directly specifies an aspect of the subtype's type. A
representation item that names a subtype is either subtype-specific (Size and
Alignment clauses) or type-related (all others). [Subtype-specific aspects may
differ for different subtypes of the same type.]

8.a         To be honest: Type-related and subtype-specific are defined
            likewise for the corresponding aspects of representation.

8.b         To be honest: Some representation items directly specify more than
            one aspect.

8.c/3       Discussion: {AI05-0229-1} For example, a pragma Export (see
            J.15.5) specifies the convention of an entity, and also specifies
            that it is exported. Such items are obsolescent; directly
            specifying the associated aspects is preferred.

8.d         Ramification: Each specifiable attribute constitutes a separate
            aspect. An enumeration_representation_clause specifies the coding
            aspect. A record_representation_clause (without the mod_clause)
            specifies the record layout aspect. Each representation pragma
            specifies a separate aspect.

8.e         Reason: We don't need to say that an at_clause or a mod_clause
            specify separate aspects, because these are equivalent to
            attribute_definition_clauses. See J.7, "At Clauses", and J.8, "
            Mod Clauses".

8.e.1/3     {AI05-0112-1} We give a default naming for representation aspects
            of representation pragmas so we don't have to do that for every
            pragma. Operational and representation attributes are given a
            default naming in 13.3. We don't want any anonymous aspects; that
            would make other rules more difficult to write and understand.

8.f         Ramification: The following representation items are type-related:

8.g           * enumeration_representation_clause

8.h           * record_representation_clause

8.i           * Component_Size clause

8.j/1         * This paragraph was deleted.{8652/0009} {AI95-00137-01}

8.k           * Small clause

8.l           * Bit_Order clause

8.m           * Storage_Pool clause

8.n           * Storage_Size clause

8.n.1/2       * {AI95-00270-01} Stream_Size clause

8.o/1         * This paragraph was deleted.{8652/0009} {AI95-00137-01}

8.p/1         * This paragraph was deleted.{8652/0009} {AI95-00137-01}

8.q/1         * This paragraph was deleted.{8652/0009} {AI95-00137-01}

8.r/1         * This paragraph was deleted.{8652/0009} {AI95-00137-01}

8.s           * Machine_Radix clause

8.t           * pragma Pack

8.u           * pragmas Import, Export, and Convention (when applied to a type)

8.v/3         * {AI05-0009-1} pragmas Atomic, Independent, and Volatile (when
                applied to a type)

8.w/3         * {AI05-0009-1} pragmas Atomic_Components,
                Independent_Components, and Volatile_Components (when applied
                to a type)

8.x           * pragma Discard_Names (when applied to an enumeration or tagged
                type)

8.y         The following representation items are subtype-specific:

8.z           * Alignment clause (when applied to a first subtype)

8.aa          * Size clause (when applied to a first subtype)

8.bb        The following representation items do not apply to subtypes, so
            they are neither type-related nor subtype-specific:

8.cc          * Address clause (applies to objects and program units)

8.dd          * Alignment clause (when applied to an object)

8.ee          * Size clause (when applied to an object)

8.ff          * pragmas Import, Export, and Convention (when applied to
                anything other than a type)

8.gg          * pragmas Atomic and Volatile (when applied to an object or a
                component)

8.hh/3        * {AI05-0009-1} pragmas Atomic_Components,
                Independent_Components, and Volatile_Components (when applied
                to an array object)

8.ii          * pragma Discard_Names (when applied to an exception)

8.jj          * pragma Asynchronous (applies to procedures)

8.kk/2        * {AI95-00414-01} pragma No_Return (applies to subprograms)

8.ll/3      {AI05-0229-1} While an aspect_specification is not a
            representation item, a similar categorization applies to the
            aspect that corresponds to each of these representation items
            (along with aspects that do not have associated representation
            items).

8.1/3 {8652/0009} {AI95-00137-01} {AI05-0183-1} An operational item directly
specifies an operational aspect of the entity denoted by the local_name,
except in the case of a type-related operational item, whose local_name shall
denote a first subtype, and which directly specifies an aspect of the type of
the subtype.

8.mm/1      Ramification: {8652/0009} {AI95-00137-01} The following
            operational items are type-related:

8.nn/1        * External_Tag clause

8.oo/1        * Read clause

8.pp/1        * Write clause

8.qq/1        * Input clause

8.rr/1        * Output clause

9/4 {AI05-0183-1} {AI12-0116-1} A representation item that directly specifies
an aspect of a subtype or type shall appear after the type is completely
defined (see 3.11.1), and before the subtype or type is frozen (see 13.14).

9.a/1       Ramification: {8652/0009} {AI95-00137-01} The fact that a
            representation item (or operational item, see next paragraph) that
            directly specifies an aspect of an entity is required to appear
            before the entity is frozen prevents changing the representation
            of an entity after using the entity in ways that require the
            representation to be known.

9.b/4       This paragraph was deleted.{AI05-0183-1} {AI12-0116-1}

9.1/4 {8652/0009} {AI95-00137-01} {AI05-0183-1} {AI12-0116-1} An operational
item that directly specifies an aspect of an entity shall appear before the
entity is frozen (see 13.14).

9.c/1       Ramification: Unlike representation items, operational items can
            be specified on partial views. Since they don't affect the
            representation, the full declaration need not be known to
            determine their legality.

9.2/4 {AI12-0116-1} If a representation item, operational item, or
aspect_specification is given that directly specifies an aspect of an entity,
then it is illegal to give another representation item, operational item, or
aspect_specification that directly specifies the same aspect of the entity.

9.c.1/4     Ramification: {AI12-0116-1} This rule applies to all aspects, not
            just those that are operational aspects or representation aspects.
            For instance, it applies to subtype predicates and type
            invariants.

9.c.2/4     To be honest: {AI12-0116-1} This rule is also intended to cover
            other ways to specify representation aspects, such as obsolescent
            pragma Priority. Priority is not a representation pragma, and as
            such is neither a representation item nor an
            aspect_specification. Regardless, giving both a pragma Priority
            and an aspect_specification for Priority is illegal. We didn't
            want to complicate the wording solely to support obsolescent
            features.

9.3/4 {AI05-0106-1} {AI05-0295-1} {AI12-0116-1} Unless otherwise specified, it
is illegal to specify an operational or representation aspect of a generic
formal parameter.

9.d/3       Reason: Specifying an aspect on a generic formal parameter implies
            an added contract for a generic unit. That contract needs to be
            defined via generic parameter matching rules, and, as aspects vary
            widely, that has to be done for each such aspect. Since most
            aspects do not need this complexity (including all
            language-defined aspects as of this writing), we avoid the
            complexity by saying that such contract-forming aspect
            specifications are banned unless the rules defining them
            explicitly exist. Note that the method of specification does not
            matter: aspect_specifications, representation items, and
            operational items are all covered by this (and similar) rules.

10/4 {AI05-0295-1} {AI12-0109-1} For an untagged derived type, it is illegal
to specify a type-related representation aspect if the parent type is a
by-reference type, or has any user-defined primitive subprograms. Similarly,
it is illegal to specify a nonconfirming type-related representation aspect
for an untagged by-reference type after one or more types have been derived
from it.

10.a/3      Ramification: {8652/0009} {AI95-00137-01} {AI05-0295-1} On the
            other hand, subtype-specific representation aspects may be
            specified for the first subtype of such a type, as can operational
            aspects.

10.b/4      Reason: {AI05-0229-1} {AI05-0295-1} {AI12-0109-1} The reason for
            forbidding specification of type-related representation aspects on
            untagged by-reference types is because a change of representation
            is impossible when passing by reference (to an inherited
            subprogram). (A by-reference object cannot be copied to change its
            representation.) The reason for forbidding specification of
            type-related representation aspects on untagged types with
            user-defined primitive subprograms was to prevent implicit change
            of representation for type-related aspects of representation upon
            calling inherited subprograms, because such changes of
            representation are likely to be expensive at run time. Changes of
            subtype-specific representation attributes, however, are likely to
            be cheap. This rule is not needed for tagged types, because other
            rules prevent a type-related representation aspect from changing
            the representation of the parent part; we want to allow specifying
            a type-related representation aspect on a type extension to
            specify aspects of the extension part. For example, specifying
            aspect Pack will cause packing of the extension part, but not of
            the parent part.

10.c/4      Discussion: {AI12-0109-1} "By-reference type" usually cannot be
            used in Legality Rules, as it is privacy breaking. Our use here is
            privacy breaking, but we're stuck with it for compatibility
            reasons. Since representation aspects cannot be specified on
            partial views, privacy violations only can happen when a type
            includes a component of a private type. In that case, whether
            these rules are triggered depends on the full type of the private
            type - which is clearly privacy breaking.

11/3 {8652/0009} {AI95-00137-01} {8652/0011} {AI95-00117-01} {AI95-00326-01}
{AI05-0295-1} Operational and representation aspects of a generic formal
parameter are the same as those of the actual. Operational and representation
aspects are the same for all views of a type. Specification of a type-related
representation aspect is not allowed for a descendant of a generic formal
untagged type.

11.a/3      Ramification: {8652/0009} {AI95-00137-01} {AI05-0295-1} Specifying
            representation aspects is allowed for types whose subcomponent
            types or index subtypes are generic formal types. Specifying
            operational aspects and subtype-related representation aspects is
            allowed on descendants of generic formal types.

11.b/3      Reason: {AI05-0295-1} Since it is not known whether a formal type
            has user-defined primitive subprograms, specifying type-related
            representation aspects for them is not allowed, unless they are
            tagged (in which case only the extension part is affected in any
            case).

11.c/2      Ramification: {AI95-00326-01} All views of a type, including the
            incomplete and partial views, have the same operational and
            representation aspects. That's important so that the properties
            don't change when changing views. While most aspects are not
            available for an incomplete view, we don't want to leave any holes
            by not saying that they are the same.

11.d/3      {AI05-0083-1} However, this does not apply to objects. Different
            views of an object can have different representation aspects. For
            instance, an actual object passed by reference and the associated
            formal parameter may have different values for Alignment even
            though the formal parameter is merely a view of the actual object.
            This is necessary to maintain the language design principle that
            Alignments are always known at compile time.

12/3 {AI05-0295-1} The specification of the Size aspect for a given subtype,
or the size or storage place for an object (including a component) of a given
subtype, shall allow for enough storage space to accommodate any value of the
subtype.

13/3 {8652/0009} {AI95-00137-01} {AI05-0295-1} If a specification of a
representation or operational aspect is not supported by the implementation,
it is illegal or raises an exception at run time.

13.1/3 {AI95-00251-01} {AI05-0295-1} A type_declaration is illegal if it has
one or more progenitors, and a nonconfirming value was specified for a
representation aspect of an ancestor, and this conflicts with the
representation of some other ancestor. The cases that cause conflicts are
implementation defined.

13.a/2      Implementation defined: The cases that cause conflicts between the
            representation of the ancestors of a type_declaration.

13.b/3      Reason: {AI05-0295-1} This rule is needed because it may be the
            case that only the combination of types in a type declaration
            causes a conflict. Thus it is not possible, in general, to reject
            the original representation item or aspect_specification. For
            instance:

13.c/2          package Pkg1 is
                   type Ifc is interface;
                   type T is tagged record
                      Fld : Integer;
                   end record;
                   for T use record
                      Fld at 0 range 0 .. Integer'Size - 1;
                   end record;
                end Pkg1;

13.d/2      Assume the implementation uses a single tag with a default offset
            of zero, and that it allows the use of nondefault locations for
            the tag (and thus accepts representation items like the one
            above). The representation item will force a nondefault location
            for the tag (by putting a component other than the tag into the
            default location). Clearly, this package will be accepted by the
            implementation. However, other declarations could cause trouble.
            For instance, the implementation could reject:

13.e/2          with Pkg1;
                package Pkg2 is
                   type NewT is new Pkg1.T and Pkg1.Ifc with null record;
                end Pkg2;

13.f/3      {AI05-0295-1} because the declarations of T and Ifc have a
            conflict in their representation items. This is clearly necessary
            (it's hard to imagine how Ifc'Class could work with the tag at a
            location other than the one it is expecting without introducing
            distributed overhead).

13.g/3      {AI05-0295-1} Conflicts will usually involve
            implementation-defined attributes (for specifying the location of
            the tag, for instance), although the example above shows that
            doesn't have to be the case. For this reason, we didn't try to
            specify exactly what causes a conflict; it will depend on the
            implementation's implementation model and what representation
            aspects it allows to be changed.

13.h/3      Implementation Note: {AI05-0295-1} An implementation can only use
            this rule to reject type_declarations where one of its ancestors
            had a nonconfirming representation value specified. An
            implementation must ensure that the default representations of
            ancestors cannot conflict.


                              Static Semantics

14  If two subtypes statically match, then their subtype-specific aspects
(Size and Alignment) are the same.

14.a/3      Reason: {AI05-0295-1} This is necessary because we allow (for
            example) conversion between access types whose designated subtypes
            statically match. Note that most aspects (including the
            subtype-specific aspects Size and Alignment) may not be specified
            for a nonfirst subtype. The only language-defined exceptions to
            this rule are the Static_Predicate and Dynamic_Predicate aspects.

14.b        Consider, for example:

14.c/1          package P1 is
                   subtype S1 is Integer range 0..2**16-1;
                   for S1'Size use 16; -- Illegal!
                      -- S1'Size would be 16 by default.
                   type A1 is access all S1;
                   X1: A1;
                end P1;

14.d/1          package P2 is
                   subtype S2 is Integer range 0..2**16-1;
                   for S2'Size use 32; -- Illegal!
                   type A2 is access all S2;
                   X2: A2;
                end P2;

14.e/3          {AI05-0229-1} procedure Q is
                   use P1, P2;
                   type Array1 is array(Integer range <>) of aliased S1
                      with Pack;
                   Obj1: Array1(1..100);
                   type Array2 is array(Integer range <>) of aliased S2
                      with Pack;
                   Obj2: Array2(1..100);
                begin
                   X1 := Obj2(17)'Unchecked_Access;
                   X2 := Obj1(17)'Unchecked_Access;
                end Q;

14.f        Loads and stores through X1 would read and write 16 bits, but X1
            points to a 32-bit location. Depending on the endianness of the
            machine, loads might load the wrong 16 bits. Stores would fail to
            zero the other half in any case.

14.g        Loads and stores through X2 would read and write 32 bits, but X2
            points to a 16-bit location. Thus, adjacent memory locations would
            be trashed.

14.h        Hence, the above is illegal. Furthermore, the compiler is
            forbidden from choosing different Sizes by default, for the same
            reason.

14.i        The same issues apply to Alignment.

15/3 {8652/0040} {AI95-00108-01} {AI05-0009-1} {AI05-0295-1} A derived type
inherits each type-related representation aspect of its parent type that was
directly specified before the declaration of the derived type, or (in the case
where the parent is derived) that was inherited by the parent type from the
grandparent type. A derived subtype inherits each subtype-specific
representation aspect of its parent subtype that was directly specified before
the declaration of the derived type, or (in the case where the parent is
derived) that was inherited by the parent subtype from the grandparent
subtype, but only if the parent subtype statically matches the first subtype
of the parent type. An inherited representation aspect is overridden by a
subsequent aspect_specification or representation item that specifies a
different value for the same aspect of the type or subtype.

15.a        To be honest: A record_representation_clause for a record
            extension does not override the layout of the parent part; if the
            layout was specified for the parent type, it is inherited by the
            record extension.

15.b        Ramification: If a representation item for the parent appears
            after the derived_type_definition, then inheritance does not
            happen for that representation item.

15.b.1/3    {AI05-0009-1} {AI05-0295-1} If an inherited aspect is confirmed by
            an aspect_specification or a later representation item for a
            derived type, the confirming specification does not override the
            inherited one. Thus the derived type has both a specified
            confirming value and an inherited nonconfirming representation
            value - this means that rules that apply only to nonconfirming
            representation values still apply to this type.

15.b.2/4    {AI12-0109-1} If an aspect was specified by an
            aspect_specification and the parent type has not yet been frozen,
            then the inherited aspect might not yet have been resolved and
            evaluated. The implementation will need to have a mechanism to
            handle such an aspect.

15.1/3 {8652/0040} {AI95-00108-01} {AI95-00444-01} {AI05-0183-1}
{AI05-0295-1} In contrast, whether operational aspects are inherited by a
derived type depends on each specific aspect; unless specified, an operational
aspect is not inherited. When operational aspects are inherited by a derived
type, aspects that were directly specified by aspect_specifications or
operational items that are visible at the point of the derived type
declaration, or (in the case where the parent is derived) that were inherited
by the parent type from the grandparent type are inherited. An inherited
operational aspect is overridden by a subsequent aspect_specification or
operational item that specifies the same aspect of the type.

15.b.3/1    Ramification: As with representation items, if an operational item
            for the parent appears after the derived_type_definition, then
            inheritance does not happen for that operational item.

15.2/2 {AI95-00444-01} When an aspect that is a subprogram is inherited, the
derived type inherits the aspect in the same way that a derived type inherits
a user-defined primitive subprogram from its parent (see 3.4).

15.c/2      Reason: This defines the parameter names and types, and the needed
            implicit conversions.

16  Each aspect of representation of an entity is as follows:

17    * If the aspect is specified for the entity, meaning that it is either
        directly specified or inherited, then that aspect of the entity is as
        specified, except in the case of Storage_Size, which specifies a
        minimum.

17.a        Ramification: This rule implies that queries of the aspect return
            the specified value. For example, if the user writes "for X'Size
            use 32;", then a query of X'Size will return 32.

18    * If an aspect of representation of an entity is not specified, it is
        chosen by default in an unspecified manner.

18.a/3      Ramification: {8652/0009} {AI95-00137-01} {AI05-0295-1} Note that
            specifying a representation aspect can affect the semantics of the
            entity.

18.b        The rules forbid things like "for S'Base'Alignment use ..." and
            "for S'Base use record ...".

18.c        Discussion: The intent is that implementations will represent the
            components of a composite value in the same way for all subtypes
            of a given composite type. Hence, Component_Size and record layout
            are type-related aspects.

18.d/3      Ramification: {AI05-0083-1} As noted previously, in the case of an
            object, the entity mentioned in this text is a specific view of an
            object. That means that only references to the same view of an
            object that has a specified value for a representation aspect R
            necessarily have that value for the aspect R. The value of the
            aspect R for a different view of that object is unspecified. In
            particular, this means that the representation values for
            by-reference parameters is unspecified; they do not have to be the
            same as those of the underlying object.

18.1/1 {8652/0040} {AI95-00108-01} If an operational aspect is specified for
an entity (meaning that it is either directly specified or inherited), then
that aspect of the entity is as specified. Otherwise, the aspect of the entity
has the default value for that aspect.

18.2/3 {AI95-00291-02} {AI05-0295-1} An aspect_specification or representation
item that specifies a representation aspect that would have been chosen in the
absence of the aspect_specification or representation item is said to be
confirming. The aspect value specified in this case is said to be a confirming
representation aspect value. Other values of the aspect are said to be
nonconfirming, as are the aspect_specifications and representation items that
specified them.


                              Dynamic Semantics

19/1 {8652/0009} {AI95-00137-01} For the elaboration of an aspect_clause, any
evaluable constructs within it are evaluated.

19.a/3      Ramification: {AI05-0299-1} Elaboration of representation pragmas
            is covered by the general rules for pragmas in 2.8.


                         Implementation Permissions

20/3 {AI05-0295-1} An implementation may interpret representation aspects in
an implementation-defined manner. An implementation may place
implementation-defined restrictions on the specification of representation
aspects. A recommended level of support is defined for the specification of
representation aspects and related features in each subclause. These
recommendations are changed to requirements for implementations that support
the Systems Programming Annex (see C.2, "Required Representation Support").

20.a/3      Implementation defined: The interpretation of each representation
            aspect.

20.b/3      Implementation defined: Any restrictions placed upon the
            specification of representation aspects.

20.c        Ramification: Implementation-defined restrictions may be enforced
            either at compile time or at run time. There is no requirement
            that an implementation justify any such restrictions. They can be
            based on avoiding implementation complexity, or on avoiding
            excessive inefficiency, for example.

20.c.1/1    {8652/0009} {AI95-00137-01} There is no such permission for
            operational aspects.


                            Implementation Advice

21/3 {AI05-0295-1} The recommended level of support for the specification of
all representation aspects is qualified as follows:

21.1/3   * {AI95-00291-02} {AI05-0295-1} A confirming specification for a
        representation aspect should be supported.

21.a/3      To be honest: {AI05-0295-1} A confirming representation aspect
            value might not be possible for some entities. For instance,
            consider an unconstrained array. The size of such a type is
            implementation-defined, and might not actually be a representable
            value, or might not be static.

22/3   * {AI05-0295-1} An implementation need not support the specification
        for a representation aspect that contains nonstatic expressions,
        unless each nonstatic expression is a name that statically denotes a
        constant declared before the entity.

22.a        Reason: This is to avoid the following sort of thing:

22.b            X : Integer := F(...);
                Y : Address := G(...);
                for X'Address use Y;

22.c        In the above, we have to evaluate the initialization expression
            for X before we know where to put the result. This seems like an
            unreasonable implementation burden.

22.d        The above code should instead be written like this:

22.e            Y : constant Address := G(...);
                X : Integer := F(...);
                for X'Address use Y;

22.f        This allows the expression "Y" to be safely evaluated before X is
            created.

22.g        The constant could be a formal parameter of mode in.

22.h        An implementation can support other nonstatic expressions if it
            wants to. Expressions of type Address are hardly ever static, but
            their value might be known at compile time anyway in many cases.

23    * An implementation need not support a specification for the Size for a
        given composite subtype, nor the size or storage place for an object
        (including a component) of a given composite subtype, unless the
        constraints on the subtype and its composite subcomponents (if any)
        are all static constraints.

24/3   * {AI95-00291-02} {AI05-0295-1} An implementation need not support
        specifying a nonconfirming representation aspect value if it could
        cause an aliased object or an object of a by-reference type to be
        allocated at a nonaddressable location or, when the alignment
        attribute of the subtype of such an object is nonzero, at an address
        that is not an integral multiple of that alignment.

24.a/1      Reason: The intent is that access types, type System.Address, and
            the pointer used for a by-reference parameter should be
            implementable as a single machine address - bit-field pointers
            should not be required. (There is no requirement that this
            implementation be used - we just want to make sure it's feasible.)

24.b/2      Implementation Note: {AI95-00291-02} We want subprograms to be
            able to assume the properties of the types of their parameters
            inside of subprograms. While many objects can be copied to allow
            this (and thus do not need limitations), aliased or by-reference
            objects cannot be copied (their memory location is part of their
            identity). Thus, the above rule does not apply to types that
            merely allow by-reference parameter passing; for such types, a
            copy typically needs to be made at the call site when a
            bit-aligned component is passed as a parameter.

25/3   * {AI95-00291-02} {AI05-0295-1} An implementation need not support
        specifying a nonconfirming representation aspect value if it could
        cause an aliased object of an elementary type to have a size other
        than that which would have been chosen by default.

25.a/2      Reason: Since all bits of elementary objects participate in
            operations, aliased objects must not have a different size than
            that assumed by users of the access type.

26/3   * {AI95-00291-02} {AI05-0295-1} An implementation need not support
        specifying a nonconfirming representation aspect value if it could
        cause an aliased object of a composite type, or an object whose type
        is by-reference, to have a size smaller than that which would have
        been chosen by default.

26.a/2      Reason: Unlike elementary objects, there is no requirement that
            all bits of a composite object participate in operations. Thus, as
            long as the object is the same or larger in size than that
            expected by the access type, all is well.

26.b/2      Ramification: This rule presumes that the implementation allocates
            an object of a size specified to be larger than the default size
            in such a way that access of the default size suffices to
            correctly read and write the value of the object.

27/3   * {AI95-00291-02} {AI05-0295-1} An implementation need not support
        specifying a nonconfirming subtype-specific representation aspect
        value for an indefinite or abstract subtype.

27.a/3      Reason: {AI05-0295-1} Representation aspects are often not
            well-defined for such types.

27.b/3      Ramification: {AI95-00291-02} {AI05-0229-1} A type with the Pack
            aspect specified will typically not be packed so tightly as to
            disobey the above rules. A Component_Size clause or
            record_representation_clause will typically be illegal if it
            disobeys the above rules. Atomic components have similar
            restrictions (see C.6, "Shared Variable Control").

28/3 {AI95-00291-02} {AI05-0295-1} For purposes of these rules, the
determination of whether specifying a representation aspect value for a type
could cause an object to have some property is based solely on the properties
of the type itself, not on any available information about how the type is
used. In particular, it presumes that minimally aligned objects of this type
might be declared at some point.

28.a/2      Implementation Advice: The recommended level of support for all
            representation items should be followed.

        NOTES

29/3    1  {AI05-0229-1} Aspects that can be specified are defined throughout
        this International Standard, and are summarized in K.1.


                        Incompatibilities With Ada 83

29.a        It is now illegal for a representation item to cause a derived
            by-reference type to have a different record layout from its
            parent. This is necessary for by-reference parameter passing to be
            feasible. This only affects programs that specify the
            representation of types derived from types containing tasks; most
            by-reference types are new to Ada 95. For example, if A1 is an
            array of tasks, and A2 is derived from A1, it is illegal to apply
            a pragma Pack to A2.


                            Extensions to Ada 83

29.b/1      {8652/0009} {AI95-00137-01} Ada 95 allows additional
            aspect_clauses for objects.


                         Wording Changes from Ada 83

29.c/1      {8652/0009} {AI95-00137-01} The syntax rule for
            type_representation_clause is removed; the right-hand side of that
            rule is moved up to where it was used, in aspect_clause. There are
            two references to "type representation clause" in RM83, both in
            Section 13; these have been reworded. Also, the
            representation_clause has been renamed the aspect_clause to
            reflect that it can be used to control more than just
            representation aspects.

29.d/2      {8652/0009} {AI95-00137-01} {AI95-00114-01} We have defined a new
            term "representation item," which includes all representation
            clauses and representation pragmas, as well as component_clauses.
            This is convenient because the rules are almost identical for all
            of them. We have also defined the new terms "operational item" and
            "operational aspects" in order to conveniently handle new types of
            specifiable entities.

29.e        All of the forcing occurrence stuff has been moved into its own
            subclause (see 13.14), and rewritten to use the term "freezing".

29.f        RM83-13.1(10) requires implementation-defined restrictions on
            representation items to be enforced at compile time. However, that
            is impossible in some cases. If the user specifies a junk
            (nonstatic) address in an address clause, and the implementation
            chooses to detect the error (for example, using hardware memory
            management with protected pages), then it's clearly going to be a
            run-time error. It seems silly to call that "semantics" rather
            than "a restriction."

29.g        RM83-13.1(10) tries to pretend that representation_clauses don't
            affect the semantics of the program. One counter-example is the
            Small clause. Ada 95 has more counter-examples. We have noted the
            opposite above.

29.h        Some of the more stringent requirements are moved to C.2, "
            Required Representation Support".


                            Extensions to Ada 95

29.i/2      {AI95-00291-02} Amendment Correction: Confirming representation
            items are defined, and the recommended level of support is now
            that they always be supported.


                         Wording Changes from Ada 95

29.j/2      {8652/0009} {AI95-00137-01} Corrigendum: Added operational items
            in order to eliminate unnecessary restrictions and permissions on
            stream attributes. As part of this, representation_clause was
            renamed to aspect_clause.

29.k/2      {8652/0009} {AI95-00137-01} {AI95-00326-01} Corrigendum: Added
            wording to say that the partial and full views have the same
            operational and representation aspects. Ada 2005 extends this to
            cover all views, including the incomplete view.

29.l/2      {8652/0040} {AI95-00108-01} Corrigendum: Changed operational items
            to have inheritance specified for each such aspect.

29.m/2      {AI95-00251-01} Added wording to allow the rejection of types with
            progenitors that have conflicting representation items.

29.n/2      {AI95-00291-02} The description of the representation of an object
            was clarified (with great difficulty reaching agreement). Added
            wording to say that representation items on aliased and
            by-reference objects never need be supported if they would not be
            implementable without distributed overhead even if other
            recommended level of support says otherwise. This wording matches
            the rules with reality.

29.o/3      {AI95-00444-01} {AI05-0005-1} Added wording so that inheritance
            depends on whether operational items are visible rather than
            whether they occur before the declaration (we don't want to look
            into private parts). Also limited operational inheritance to
            untagged types to avoid anomalies with private extensions (this is
            not incompatible, no existing operational attribute used this
            capability). Also added wording to clearly define that subprogram
            inheritance works like derivation of subprograms.


                       Incompatibilities With Ada 2005

29.p/3      {AI05-0106-1} Correction: Specifying a language-defined aspect for
            a generic formal parameter is no longer allowed. Most aspects
            could not be specified on these anyway; moreover, this was not
            allowed in Ada 83, so it is unlikely that compilers are supporting
            this as a capability (and it is not likely that they have a
            consistent definition of what it means if it is allowed). Thus, we
            expect this to occur rarely in existing programs.


                        Wording Changes from Ada 2005

29.q/3      {AI05-0009-1} Correction: Defined that overriding of an
            representation aspect only happens for a nonconfirming
            representation item. This prevents a derived type from being
            considered to have only a confirming representation item when the
            value would be nonconfirming if given on a type that does not
            inherit any aspects of representation. This change just eliminates
            a wording confusion and ought not change any behavior.

29.r/3      {AI05-0112-1} Correction: Defined a default naming for
            representation aspects that are representation pragmas.

29.s/3      {AI05-0183-1} Added text ensuring that the rules for
            representational and operational items also apply appropriately to
            aspect_specifications; generalized operational aspects so that
            they can be defined for entities other than types. Any extensions
            are documented elsewhere.

29.t/3      {AI05-0295-1} Rewrote many rules to be in terms of "specifying a
            representation aspect" rather than use of a "representation item".
            This better separates how an aspect is specified from what rules
            apply to the value of the aspect.


                       Incompatibilities With Ada 2012

29.u/4      {AI12-0109-1} Corrigendum: Added a rule that makes it illegal to
            specify a representation value after a type is derived from an
            untagged by-reference type. This restriction is incompatible, but
            since the implementation would have had to copy an object that
            does not allow copying in order to change the representation for
            any implicit or explicit conversion between the original and the
            derived type, it is unlikely that any program could exist without
            running into internal compiler errors or bogus results.


                        Wording Changes from Ada 2012

29.v/4      {AI12-0116-1} Corrigendum: Clarified that an aspect (any aspect)
            can be specified only once for an entity, no matter what means of
            specifying it are used. We did not document this as an
            incompatibility as only aspects that are neither operational nor
            representation could change behavior and there is no known
            implementation of these new aspects that allows multiple
            definitions.


13.1.1 Aspect Specifications


1/3 {AI05-0183-1} [Certain representation or operational aspects of an entity
may be specified as part of its declaration using an aspect_specification,
rather than using a separate representation or operational item.] The
declaration with the aspect_specification is termed the associated
declaration.


                                   Syntax

2/3     {AI05-0183-1} aspect_specification ::= 
           with aspect_mark [=> aspect_definition] {,
                   aspect_mark [=> aspect_definition] }

3/3     {AI05-0183-1} aspect_mark ::= aspect_identifier['Class]

4/3     {AI05-0183-1} aspect_definition ::= name | expression | identifier


                         Language Design Principles

4.a/3       {AI05-0183-1} {AI05-0267-1} The aspect_specification is an
            optional element in most kinds of declarations. Here is a list of
            all kinds of declarations and an indication of whether or not they
            allow aspect clauses, and in some cases a short discussion of why
            (* = allowed, NO = not allowed). Kinds of declarations with no
            indication are followed by their subdivisions (which have
            indications).

4.b/4           {AI12-0005-1} basic_declaration
                  type_declaration
                    full_type_declaration
                      type declaration syntax*
                      task_type_declaration*
                      protected_type_declaration*
                    incomplete_type_declaration  --  NO
                      -- Incomplete type aspects cannot be read by an attribute or specified by attribute_definition_clause
                s 
                      -- (the attribute name is illegal), so it would not make sense to allow this in another way.
                    private_type_declaration*
                    private_extension_declaration*
                  subtype_declaration*
                  object_declaration
                    object declaration syntax*
                    single_task_declaration*
                    single_protected_declaration*
                  number_declaration  --  NO
                  subprogram_declaration*
                  abstract_subprogram_declaration*
                  null_procedure_declaration*
                  expression_function_declaration*
                  package_declaration*  -- via package_specification
                  renaming_declaration*
                    -- There are no language-defined aspects that may be specified
                    -- on renames, but implementations might support some.
                  exception_declaration*
                  generic_declaration
                    generic_subprogram_declaration*
                    generic_package_declaration
                * -- via package_specification
                  generic_instantiation*
                enumeration_literal_specification  --  NO
                discriminant_specification  --  NO
                component_declaration*
                loop_parameter_specification  --  NO
                iterator_specification  --  NO
                parameter_specification  --  NO
                subprogram_body
                *  --   - but language-defined aspects only if there is no explicit specification
                entry_declaration*
                entry_index_specification  --  NO
                subprogram_body_stub
                *  --   - but language-defined aspects only if there is no explicit specification
                choice_parameter_specification  --  NO
                generic_formal_parameter_declaration
                    -- There are no language-defined aspects that may be specified
                    -- on generic formals, but implementations might support some.
                  formal_object_declaration*
                  formal_type_declaration*
                  formal_subprogram_declaration
                    formal_concrete_subprogram_declaration*
                    formal_abstract_subprogram_declaration*
                  formal_package_declaration*
                extended_return_statement  --  NO

4.c/3           -- We also allow aspect_specification
                s on all kinds of bodies, but are no language-defined aspects
                -- that may be specified on a body. These are allowed for implementation-defined aspects.
                -- See above for subprogram bodies and stubs (as these can be declarations).
                package_body*
                task_body*
                protected_body*
                package_body_stub*
                task_body_stub*
                protected_body_stub*

4.d/3       {AI05-0267-1} Syntactically, aspect_specifications generally are
            located at the end of declarations. When a declaration is all in
            one piece such as a null_procedure_declaration,
            object_declaration, or generic_instantiation the
            aspect_specification goes at the end of the declaration; it is
            then more visible and less likely to interfere with the layout of
            the rest of the structure. However, we make an exception for
            program units (other than subprogram specifications) and bodies,
            in which the aspect_specification goes before the is. In these
            cases, the entity could be large and could contain other
            declarations that also have aspect_specifications, so it is better
            to put the aspect_specification toward the top of the declaration.
            (Some aspects - such as Pure - also affect the legality of the
            contents of a unit, so it would be annoying to only see those
            after reading the entire unit.)


                            Name Resolution Rules

5/3 {AI05-0183-1} An aspect_mark identifies an aspect of the entity defined by
the associated declaration (the associated entity); the aspect denotes an
object, a value, an expression, a subprogram, or some other kind of entity. If
the aspect_mark identifies:

6/3   * an aspect that denotes an object, the aspect_definition shall be a
        name. The expected type for the name is the type of the identified
        aspect of the associated entity;

7/3   * an aspect that is a value or an expression, the aspect_definition
        shall be an expression. The expected type for the expression is the
        type of the identified aspect of the associated entity;

8/3   * an aspect that denotes a subprogram, the aspect_definition shall be a
        name; the expected profile for the name is the profile required for
        the aspect of the associated entity;

9/3   * an aspect that denotes some other kind of entity, the
        aspect_definition shall be a name, and the name shall resolve to
        denote an entity of the appropriate kind;

10/3   * an aspect that is given by an identifier specific to the aspect, the
        aspect_definition shall be an identifier, and the identifier shall be
        one of the identifiers specific to the identified aspect.

11/3 {AI05-0183-1} The usage names in an aspect_definition [ are not resolved
at the point of the associated declaration, but rather] are resolved at the
end of the immediately enclosing declaration list.

12/3 {AI05-0183-1} If the associated declaration is for a subprogram or entry,
the names of the formal parameters are directly visible within the
aspect_definition, as are certain attributes, as specified elsewhere in this
International Standard for the identified aspect. If the associated
declaration is a type_declaration, within the aspect_definition the names of
any components are directly visible, and the name of the first subtype denotes
the current instance of the type (see 8.6). If the associated declaration is a
subtype_declaration, within the aspect_definition the name of the new subtype
denotes the current instance of the subtype.


                               Legality Rules

13/3 {AI05-0183-1} If the first freezing point of the associated entity comes
before the end of the immediately enclosing declaration list, then each usage
name in the aspect_definition shall resolve to the same entity at the first
freezing point as it does at the end of the immediately enclosing declaration
list.

14/3 {AI05-0183-1} At most one occurrence of each aspect_mark is allowed
within a single aspect_specification. The aspect identified by the
aspect_mark shall be an aspect that can be specified for the associated entity
(or view of the entity defined by the associated declaration).

14.a/4      Ramification: {AI12-0116-1} This rule prevents multiple
            specifications in the same aspect_specification. Rules in 13.1
            prevent multiple specifications in different
            aspect_specifications (on different views of the same type, for
            instance) or between operational or representation items and an
            aspect_specification, even for aspects that are neither
            operational nor representation aspects.

15/3 {AI05-0183-1} The aspect_definition associated with a given aspect_mark
may be omitted only when the aspect_mark identifies an aspect of a boolean
type, in which case it is equivalent to the aspect_definition being specified
as True.

16/3 {AI05-0183-1} If the aspect_mark includes 'Class, then the associated
entity shall be a tagged type or a primitive subprogram of a tagged type.

17/3 {AI05-0183-1} {AI05-0267-1} There are no language-defined aspects that
may be specified on a renaming_declaration, a
generic_formal_parameter_declaration, a subunit, a package_body, a task_body,
a protected_body, or a body_stub other than a subprogram_body_stub.

17.a/3      Discussion: Implementation-defined aspects can be allowed on
            these, of course; the implementation will need to define the
            semantics. In particular, the implementation will need to define
            actual type matching rules for any aspects allowed on formal
            types; there are no default matching rules defined by the
            language.

18/4 {AI05-0183-1} {AI05-0267-1} {AI12-0105-1} A language-defined aspect shall
not be specified in an aspect_specification given on a completion of a
subprogram or generic subprogram.

18.a/3      Reason: Most language-defined aspects (for example, preconditions)
            are intended to be available to callers, and specifying them on a
            body that has a separate declaration hides them from callers.
            Specific language-defined aspects may allow this, but they have to
            do so explicitly (by defining an alternative Legality Rule), and
            provide any needed rules about visibility. Note that this rule
            does not apply to implementation-defined aspects, so implementers
            need to carefully define whether such aspects can be applied to
            bodies and stubs, and what happens if they are specified on both
            the declaration and body of a unit.

18.1/4 {AI05-0183-1} {AI12-0138-1} If an aspect of a derived type is inherited
from an ancestor type and has the boolean value True, the inherited value
shall not be overridden to have the value False for the derived type, unless
otherwise specified in this International Standard.

18.2/4 {AI12-0138-1} Certain type-related aspects are defined to be
nonoverridable; all such aspects are specified using an aspect_definition that
is a name.

18.3/4 {AI12-0138-1} If a nonoverridable aspect is directly specified for a
type T, then any explicit specification of that aspect for any other
descendant of T shall be confirming; that is, the specified name shall match
the inherited aspect, meaning that the specified name shall denote the same
declarations as would the inherited name.

18.4/4 {AI12-0138-1} If a full type has a partial view, and a given
nonoverridable aspect is allowed for both the full view and the partial view,
then the given aspect for the partial view and the full view shall be the
same: the aspect shall be directly specified only on the partial view; if the
full type inherits the aspect, then a matching definition shall be specified
(directly or by inheritance) for the partial view.

18.b        Ramification: In order to enforce these rules without breaking
            privacy, we cannot allow a private type that could have a
            particular overridable aspect to have a hidden definition of that
            aspect. There is no problem if the private type does not allow the
            aspect (as the aspect could not be specified on descendants in
            that case).

18.5/4 {AI12-0138-1} In addition to the places where Legality Rules normally
apply (see 12.3), these rules about nonoverridable aspects also apply in the
private part of an instance of a generic unit.

18.6/4 {AI12-0138-1} [The Default_Iterator, Iterator_Element,
Implicit_Dereference, Constant_Indexing, and Variable_Indexing aspects are
nonoverridable.]

18.c/4      Discussion: We don't need an assume-the-worst rule for most
            nonoverridable aspects as they only work on tagged types and
            deriving from formal tagged types is not allowed in generic
            bodies. In the case of Implicit_Dereference, a derivation in a
            generic body does not cause problems (the ancestor necessarily
            cannot have the aspect, else specifying the aspect would be
            illegal), as there could be no place with visibility on both
            aspects.


                              Static Semantics

19/3 {AI05-0183-1} Depending on which aspect is identified by the
aspect_mark, an aspect_definition specifies:

20/3   * a name that denotes a subprogram, object, or other kind of entity;

21/3   * an expression, which is either evaluated to produce a single value,
        or which (as in a precondition) is to be evaluated at particular
        points during later execution; or

22/3   * an identifier specific to the aspect.

23/3 {AI05-0183-1} The identified aspect of the associated entity, or in some
cases, the view of the entity defined by the declaration, is as specified by
the aspect_definition (or by the default of True when boolean). Whether an
aspect_specification applies to an entity or only to the particular view of
the entity defined by the declaration is determined by the aspect_mark and the
kind of entity. The following aspects are view specific:

24/3   * An aspect specified on an object_declaration;

25/3   * An aspect specified on a subprogram_declaration;

26/3   * An aspect specified on a renaming_declaration.

27/3 {AI05-0183-1} All other aspect_specifications are associated with the
entity, and apply to all views of the entity, unless otherwise specified in
this International Standard.

28/4 {AI05-0183-1} {AI12-0106-1} If the aspect_mark includes 'Class (a
class-wide aspect), then, unless specified otherwise for a particular
class-wide aspect:

29/3   * if the associated entity is a tagged type, the specification applies
        to all descendants of the type;

30/3   * if the associated entity is a primitive subprogram of a tagged type
        T, the specification applies to the corresponding primitive subprogram
        of all descendants of T.

31/3 {AI05-0183-1} {AI05-0229-1} All specifiable operational and
representation attributes may be specified with an aspect_specification
instead of an attribute_definition_clause (see 13.3).

31.a/3      Ramification: The name of the aspect is the same as that of the
            attribute (see 13.3), so the aspect_mark is the
            attribute_designator of the attribute.

32/4 {AI05-0229-1} {AI12-0154-1} Any aspect specified by a representation
pragma or library unit pragma that has a local_name as its single argument may
be specified by an aspect_specification, with the entity being the
local_name. The aspect_definition is expected to be of type Boolean. The
expression shall be static. Notwithstanding what this International Standard
says elsewhere, the expression of an aspect that can be specified by a library
unit pragma is resolved and evaluated at the point where it occurs in the
aspect_specification[, rather than the first freezing point of the associated
package].

32.a/3      Ramification: The name of the aspect is the same as that of the
            pragma (see 13.1), so the aspect_mark is the name of the pragma.

33/3 {AI05-0229-1} In addition, other operational and representation aspects
not associated with specifiable attributes or representation pragmas may be
specified, as specified elsewhere in this International Standard.

34/4 This paragraph was deleted.{AI05-0183-1} {AI12-0138-1}

35/3 {AI05-0183-1} If a Legality Rule or Static Semantics rule only applies
when a particular aspect has been specified, the aspect is considered to have
been specified only when the aspect_specification or
attribute_definition_clause is visible (see 8.3) at the point of the
application of the rule.

35.a/3      Reason: Some rules only apply when an aspect has been specified
            (for instance, an indexable type is one that has aspect
            Variable_Indexing specified). In order to prevent privacy
            breaking, this can only be true when the specification of the
            aspect is visible. In particular, if the Variable_Indexing aspect
            is specified on the full view of a private type, the private type
            is not considered an indexable type.

36/3 {AI05-0183-1} Alternative legality and semantics rules may apply for
particular aspects, as specified elsewhere in this International Standard.


                              Dynamic Semantics

37/3 {AI05-0183-1} At the freezing point of the associated entity, the
aspect_specification is elaborated. The elaboration of the
aspect_specification includes the evaluation of the name or expression, if
any, unless the aspect itself is an expression. If the corresponding aspect
represents an expression (as in a precondition), the elaboration has no
effect; the expression is evaluated later at points within the execution as
specified elsewhere in this International Standard for the particular aspect.


                         Implementation Permissions

38/3 {AI05-0183-1} Implementations may support implementation-defined aspects.
The aspect_specification for an implementation-defined aspect may use an
implementation-defined syntax for the aspect_definition, and may follow
implementation-defined legality and semantics rules.

38.a/3      Discussion: The intent is to allow implementations to support
            aspects that are defined, for example, by a subtype_indication
            rather than an expression or a name. We chose not to try to
            enumerate all possible aspect_definition syntaxes, but to give
            implementations maximum freedom. Unrecognized aspects are illegal
            whether or not they use custom syntax, so this freedom does not
            reduce portability.

38.a.1/3    Implementation defined: Implementation-defined aspects, inluding
            the syntax for specifying such aspects and the legality rules for
            such aspects.


                           Extensions to Ada 2005

38.b/3      {AI05-0183-1} {AI05-0229-1} {AI05-0267-1} Aspect specifications
            are new.


                       Incompatibilities With Ada 2012

38.c/4      {AI12-0154-1} Corrigendum: Added a clarification that aspects that
            correspond to library unit pragmas are resolved and evaluated
            immediately. This is incompatible, as a reference to an entity
            defined after the aspect will now be illegal. However, this would
            have require retroactive enforcement of such aspects, which is a
            new capability not available from the associated pragma, and
            moreover no known Ada 2012 implementation has ever allowed late
            evaluation of such aspects. As such, there should be no practical
            incompatibility.


                        Wording Changes from Ada 2012

38.d/4      {AI125-0105-1} Corrigendum: Clarified the wording so that the
            restriction against language-defined aspects on subprogram
            completions includes completions that are expressions functions
            and null procedures.

38.e/4      {AI125-0106-1} Corrigendum: Defined class-wide aspect for use in
            rules in 13.13.2.

38.f/4      {AI125-0138-1} Corrigendum: Added a definition of nonoverridable
            aspects. This is necessary to prevent generic contract problems
            with formal derived types.


13.2 Packed Types


1/3 {AI05-0229-1} [The Pack aspect having the value True specifies that
storage minimization should be the main criterion when selecting the
representation of a composite type.]

Paragraphs 2 through 4 were moved to Annex J, "Obsolescent Features".


                         Language Design Principles

1.a/4       {AI12-0001-1} If the default representation already uses minimal
            storage for a particular type, aspect Pack might not cause any
            representation change. It follows that aspect Pack should always
            be allowed, even when it has no effect on representation.

1.b/4       As a consequence, the chosen representation for a packed type may
            change during program maintenance even if the type is unchanged
            (in particular, if other representation aspects change on a part
            of the type). This is different than the behavior of most other
            representation aspects, whose properties remain guaranteed no
            matter what changes are made to other aspects.

1.c/4       Therefore, aspect Pack should not be used to achieve a
            representation required by external criteria. For instance,
            setting Component_Size to 1 should be preferred over using aspect
            Pack to ensure an array of bits. If future maintenance would make
            the array components aliased, independent, or atomic, the program
            would become illegal if Component_Size is used (immediately
            identifying a problem) while the aspect Pack version would simply
            change representations (probably causing a hard-to-find bug).


                              Static Semantics

5/3 {AI05-0229-1} For a full type declaration of a composite type, the
following language-defined representation aspect may be specified:

5.1/3 Pack      The type of aspect Pack is Boolean. When aspect Pack is True
                for a type, the type (or the extension part) is said to be
                packed. For a type extension, the parent part is packed as for
                the parent type, and specifying Pack causes packing only of
                the extension part.

5.a/3       Aspect Description for Pack: Minimize storage when laying out
            records and arrays.

5.2/3           If directly specified, the aspect_definition shall be a static
                expression. If not specified (including by inheritance), the
                aspect is False.

5.b/3       Ramification: {AI05-0229-1} The only high level semantic effect of
            specifying the Pack aspect is potential loss of independent
            addressability (see 9.10, "Shared Variables").]


                            Implementation Advice

6   If a type is packed, then the implementation should try to minimize
storage allocated to objects of the type, possibly at the expense of speed of
accessing components, subject to reasonable complexity in addressing
calculations.

6.a.1/2     Implementation Advice: Storage allocated to objects of a packed
            type should be minimized.

6.a/3       Ramification: {AI05-0229-1} Specifying the Pack aspect is for
            gaining space efficiency, possibly at the expense of time. If more
            explicit control over representation is desired, then a
            record_representation_clause, a Component_Size clause, or a Size
            clause should be used instead of, or in addition to, the Pack
            aspect.

6.1/4 This paragraph was deleted.{AI95-00291-02} {AI12-0001-1}

7/3 {AI05-0229-1} The recommended level of support for the Pack aspect is:

7.1/4   * {AI12-0001-1} Any component of a packed type that is of a
        by-reference type, that is specified as independently addressable, or
        that contains an aliased part, shall be aligned according to the
        alignment of its subtype.

7.a/4       Ramification: This also applies to atomic components. "Atomic"
            implies "specified as independently addressable", so we don't need
            to mention atomic here.

7.b/4       Other components do not have to respect the alignment of the
            subtype when packed; in many cases, the Recommended Level of
            Support will require the alignment to be ignored.

8/4   * {AI12-0001-1} For a packed record type, the components should be
        packed as tightly as possible subject to the above alignment
        requirements, the Sizes of the component subtypes, and any
        record_representation_clause that applies to the type; the
        implementation may, but need not, reorder components or cross aligned
        word boundaries to improve the packing. A component whose Size is
        greater than the word size may be allocated an integral number of
        words.

8.a         Ramification: The implementation can always allocate an integral
            number of words for a component that will not fit in a word. The
            rule also allows small component sizes to be rounded up if such
            rounding does not waste space. For example, if Storage_Unit = 8,
            then a component of size 8 is probably more efficient than a
            component of size 7 plus a 1-bit gap (assuming the gap is needed
            anyway).

9/4   * {AI05-0009-1} {AI12-0001-1} For a packed array type, if the Size of
        the component subtype is less than or equal to the word size,
        Component_Size should be less than or equal to the Size of the
        component subtype, rounded up to the nearest factor of the word size,
        unless this would violate the above alignment requirements.

9.a/4       This paragraph was deleted.{AI12-0001-1}

9.b/3       Implementation Advice: The recommended level of support for the
            Pack aspect should be followed.


                         Wording Changes from Ada 95

9.c/3       {AI95-00291-02} {AI05-0229-1} Added clarification that the Pack
            aspect can ignore alignment requirements on types that don't have
            by-reference or aliased parts. This was always intended, but there
            was no wording to that effect.


                           Extensions to Ada 2005

9.d/3       {AI05-0229-1} Aspect Pack is new; pragma Pack is now obsolescent.


                        Wording Changes from Ada 2005

9.e/3       {AI05-0009-1} Correction: Fixed so that the presence or absence of
            a confirming Component_Size representation clause does not change
            the meaning of the Pack aspect.


                        Wording Changes from Ada 2012

9.f/4       {AI12-0001-1} Corrigendum: Fixed so that the Recommended Level of
            Support does not require packing of components for which such
            packing would violate other representation items or aspects. This
            is not incompatible, as either such Pack aspects were treated as
            illegal or the Recommended Level of Support was ignored as
            impractical, neither of which would change the behavior of any
            working programs. (Other behavior cannot be justifed from the
            Standard.)


13.3 Operational and Representation Attributes


1/1 {8652/0009} {AI95-00137-01} [ The values of certain
implementation-dependent characteristics can be obtained by interrogating
appropriate operational or representation attributes. Some of these attributes
are specifiable via an attribute_definition_clause.]


                         Language Design Principles

1.a         In general, the meaning of a given attribute should not depend on
            whether the attribute was specified via an
            attribute_definition_clause, or chosen by default by the
            implementation.


                                   Syntax

2       attribute_definition_clause ::= 
              for local_name'attribute_designator use expression;
            | for local_name'attribute_designator use name;


                            Name Resolution Rules

3   For an attribute_definition_clause that specifies an attribute that
denotes a value, the form with an expression shall be used. Otherwise, the
form with a name shall be used.

4   For an attribute_definition_clause that specifies an attribute that
denotes a value or an object, the expected type for the expression or name is
that of the attribute. For an attribute_definition_clause that specifies an
attribute that denotes a subprogram, the expected profile for the name is the
profile required for the attribute. For an attribute_definition_clause that
specifies an attribute that denotes some other kind of entity, the name shall
resolve to denote an entity of the appropriate kind.

4.a         Ramification: For example, the Size attribute is of type
            universal_integer. Therefore, the expected type for Y in "for
            X'Size use Y;" is universal_integer, which means that Y can be of
            any integer type.

4.b         Discussion: For attributes that denote subprograms, the required
            profile is indicated separately for the individual attributes.

4.c         Ramification: For an attribute_definition_clause with a name, the
            name need not statically denote the entity it denotes. For
            example, the following kinds of things are allowed:

4.d             for Some_Access_Type'Storage_Pool use Storage_Pool_Array(I);
                for Some_Type'Read use Subprogram_Pointer.all;


                               Legality Rules

5/3 {8652/0009} {AI95-00137-01} {AI05-0183-1} An attribute_designator is
allowed in an attribute_definition_clause only if this International Standard
explicitly allows it, or for an implementation-defined attribute if the
implementation allows it. Each specifiable attribute constitutes an
operational aspect or aspect of representation; the name of the aspect is that
of the attribute.

5.a         Discussion: For each specifiable attribute, we generally say
            something like, "The ... attribute may be specified for ... via an
            attribute_definition_clause."

5.b         The above wording allows for T'Class'Alignment, T'Class'Size,
            T'Class'Input, and T'Class'Output to be specifiable.

5.c         A specifiable attribute is not necessarily specifiable for all
            entities for which it is defined. For example, one is allowed to
            ask T'Component_Size for an array subtype T, but "for
            T'Component_Size use ..." is only allowed if T is a first subtype,
            because Component_Size is a type-related aspect.

6   For an attribute_definition_clause that specifies an attribute that
denotes a subprogram, the profile shall be mode conformant with the one
required for the attribute, and the convention shall be Ada. Additional
requirements are defined for particular attributes.

6.a         Ramification: This implies, for example, that if one writes:

6.b             for T'Read use R;

6.c         R has to be a procedure with two parameters with the appropriate
            subtypes and modes as shown in 13.13.2.


                              Static Semantics

7/2 {AI95-00270-01} A Size clause is an attribute_definition_clause whose
attribute_designator is Size. Similar definitions apply to the other
specifiable attributes.

7.a         To be honest: An attribute_definition_clause is type-related or
            subtype-specific if the attribute_designator denotes a
            type-related or subtype-specific attribute, respectively.

8   A storage element is an addressable element of storage in the machine. A
word is the largest amount of storage that can be conveniently and efficiently
manipulated by the hardware, given the implementation's run-time model. A word
consists of an integral number of storage elements.

8.a         Discussion: A storage element is not intended to be a single bit,
            unless the machine can efficiently address individual bits.

8.b         Ramification: For example, on a machine with 8-bit storage
            elements, if there exist 32-bit integer registers, with a full set
            of arithmetic and logical instructions to manipulate those
            registers, a word ought to be 4 storage elements - that is, 32
            bits.

8.c         Discussion: The "given the implementation's run-time model" part
            is intended to imply that, for example, on an 80386 running
            MS-DOS, the word might be 16 bits, even though the hardware can
            support 32 bits.

8.d         A word is what ACID refers to as a "natural hardware boundary".

8.e         Storage elements may, but need not be, independently addressable
            (see 9.10, "Shared Variables"). Words are expected to be
            independently addressable.

8.1/3 {AI95-00133-01} {AI05-0092-1} A machine scalar is an amount of storage
that can be conveniently and efficiently loaded, stored, or operated upon by
the hardware. Machine scalars consist of an integral number of storage
elements. The set of machine scalars is implementation defined, but includes
at least the storage element and the word. Machine scalars are used to
interpret component_clauses when the nondefault bit ordering applies.

8.e.1/2     Implementation defined: The set of machine scalars.

8.f/3       Ramification: {AI05-0092-1} A single storage element is a machine
            scalar in all Ada implementations. Similarly, a word is a machine
            scalar in all implementations (although it might be the same as a
            storage element). An implementation may define other machine
            scalars that make sense on the target (a half-word, for instance).

9/3 {8652/0009} {AI95-00137-01} {AI05-0191-1} The following representation
attributes are defined: Address, Alignment, Size, Storage_Size,
Component_Size, Has_Same_Storage, and Overlaps_Storage.

10/1 For a prefix X that denotes an object, program unit, or label:

11  X'Address   Denotes the address of the first of the storage elements
                allocated to X. For a program unit or label, this value refers
                to the machine code associated with the corresponding body or
                statement. The value of this attribute is of type
                System.Address.

11.a        Ramification: Here, the "first of the storage elements" is
            intended to mean the one with the lowest address; the endianness
            of the machine doesn't matter.

11.1/3          {AI05-0095-1} The prefix of X'Address shall not statically
                denote a subprogram that has convention Intrinsic. X'Address
                raises Program_Error if X denotes a subprogram that has
                convention Intrinsic.

12              Address may be specified for stand-alone objects and for
                program units via an attribute_definition_clause.

12.a        Ramification: Address is not allowed for enumeration literals,
            predefined operators, derived task types, or derived protected
            types, since they are not program units.

12.b/3      Address is not allowed for intrinsic subprograms, either. That can
            be checked statically unless the prefix is a generic formal
            subprogram and the attribute reference is in the body of a generic
            unit. We define that case to raise Program_Error, in order that
            the compiler does not have to build a wrapper for intrinsic
            subprograms.

12.c        The validity of a given address depends on the run-time model;
            thus, in order to use Address clauses correctly, one needs
            intimate knowledge of the run-time model.

12.d/3      {AI05-0229-1} If the Address of an object is specified, any
            explicit or implicit initialization takes place as usual, unless
            the Import aspect is also specified for the object (in which case
            any necessary initialization is presumably done in the foreign
            language).

12.e        Any compilation unit containing an attribute_reference of a given
            type depends semantically on the declaration of the package in
            which the type is declared, even if not mentioned in an applicable
            with_clause - see 10.1.1. In this case, it means that if a
            compilation unit contains X'Address, then it depends on the
            declaration of System. Otherwise, the fact that the value of
            Address is of a type in System wouldn't make sense; it would
            violate the "legality determinable via semantic dependences"
            Language Design Principle.

12.f        AI83-00305 - If X is a task type, then within the body of X, X
            denotes the current task object; thus, X'Address denotes the
            object's address.

12.g        Interrupt entries and their addresses are described in J.7.1, "
            Interrupt Entries".

12.h        If X is not allocated on a storage element boundary, X'Address
            points at the first of the storage elements that contains any part
            of X. This is important for the definition of the Position
            attribute to be sensible.

12.i/3      Aspect Description for Address: Machine address of an entity.


                             Erroneous Execution

13/3 {AI05-0009-1} If an Address is specified, it is the programmer's
responsibility to ensure that the address is valid and appropriate for the
entity and its use; otherwise, program execution is erroneous.

13.a        Discussion: "Appropriate for the entity and its use" covers cases
            such as misaligned addresses, read-only code addresses for
            variable data objects (and nonexecutable data addresses for code
            units), and addresses which would force objects that are supposed
            to be independently addressable to not be. Such addresses may be
            "valid" as they designate locations that are accessible to the
            program, but the program execution is still erroneous (meaning
            that implementations do not have to worry about these cases).


                            Implementation Advice

14  For an array X, X'Address should point at the first component of the
array, and not at the array bounds.

14.a.1/2    Implementation Advice: For an array X, X'Address should point at
            the first component of the array rather than the array bounds.

14.a        Ramification: On the other hand, we have no advice to offer about
            discriminants and tag fields; whether or not the address points at
            them is not specified by the language. If discriminants are stored
            separately, then the Position of a discriminant might be negative,
            or might raise an exception.

15  The recommended level of support for the Address attribute is:

16    * X'Address should produce a useful result if X is an object that is
        aliased or of a by-reference type, or is an entity whose Address has
        been specified.

16.a        Reason: Aliased objects are the ones for which the
            Unchecked_Access attribute is allowed; hence, these have to be
            allocated on an addressable boundary anyway. Similar
            considerations apply to objects of a by-reference type.

16.b        An implementation need not go to any trouble to make Address work
            in other cases. For example, if an object X is not aliased and not
            of a by-reference type, and the implementation chooses to store it
            in a register, X'Address might return System.Null_Address
            (assuming registers are not addressable). For a subprogram whose
            calling convention is Intrinsic, or for a package, the
            implementation need not generate an out-of-line piece of code for
            it.

17    * An implementation should support Address clauses for imported
        subprograms.

18/2   * This paragraph was deleted.{AI95-00291-02}

18.a/2      This paragraph was deleted.

19    * If the Address of an object is specified, or it is imported or
        exported, then the implementation should not perform optimizations
        based on assumptions of no aliases.

19.a/2      Implementation Advice: The recommended level of support for the
            Address attribute should be followed.

        NOTES

20      2  The specification of a link name with the Link_Name aspect (see
        B.1) for a subprogram or object is an alternative to explicit
        specification of its link-time address, allowing a link-time directive
        to place the subprogram or object within memory.

21      3  The rules for the Size attribute imply, for an aliased object X,
        that if X'Size = Storage_Unit, then X'Address points at a storage
        element containing all of the bits of X, and only the bits of X.


                         Wording Changes from Ada 83

21.a        The intended meaning of the various attributes, and their
            attribute_definition_clauses, is more explicit.

21.b        The address_clause has been renamed to at_clause and moved to
            Annex J, "Obsolescent Features". One can use an Address clause
            ("for T'Address use ...;") instead.

21.c        The attributes defined in RM83-13.7.3 are moved to Annex G,
            A.5.3, and A.5.4.


                        Wording Changes from Ada 2005

21.c.1/3    {AI05-0183-1} Defined that the names of aspects are the same as
            the name of the attribute; that gives a name to use in
            aspect_specifications (see 13.1.1).


                         Language Design Principles

21.d        By default, the Alignment of a subtype should reflect the "
            natural" alignment for objects of the subtype on the machine. The
            Alignment, whether specified or default, should be known at
            compile time, even though Addresses are generally not known at
            compile time. (The generated code should never need to check at
            run time the number of zero bits at the end of an address to
            determine an alignment).

21.e        There are two symmetric purposes of Alignment clauses, depending
            on whether or not the implementation has control over object
            allocation. If the implementation allocates an object, the
            implementation should ensure that the Address and Alignment are
            consistent with each other. If something outside the
            implementation allocates an object, the implementation should be
            allowed to assume that the Address and Alignment are consistent,
            but should not assume stricter alignments than that.


                              Static Semantics

22/2 {AI95-00291-02} For a prefix X that denotes an object:

23/2 X'Alignment
                {AI95-00291-02} The value of this attribute is of type
                universal_integer, and nonnegative; zero means that the object
                is not necessarily aligned on a storage element boundary. If
                X'Alignment is not zero, then X is aligned on a storage unit
                boundary and X'Address is an integral multiple of X'Alignment
                (that is, the Address modulo the Alignment is zero).

24/2            This paragraph was deleted.{AI95-00291-02}

24.a        Ramification: The Alignment is passed by an allocator to the
            Allocate operation; the implementation has to choose a value such
            that if the address returned by Allocate is aligned as requested,
            the generated code can correctly access the object.

24.b        The above mention of "modulo" is referring to the "mod" operator
            declared in System.Storage_Elements; if X mod N = 0, then X is by
            definition aligned on an N-storage-element boundary.

25/2            {AI95-00291-02} Alignment may be specified for [stand-alone]
                objects via an attribute_definition_clause; the expression of
                such a clause shall be static, and its value nonnegative.

25.a/3      Aspect Description for Alignment (object): Alignment of an object.

26/2            This paragraph was deleted.{AI95-00247-01}

26.1/2 {AI95-00291-02} For every subtype S:

26.2/2 S'Alignment
                {AI95-00291-02} The value of this attribute is of type
                universal_integer, and nonnegative.

26.3/2          {AI95-00051-02} {AI95-00291-02} For an object X of subtype S,
                if S'Alignment is not zero, then X'Alignment is a nonzero
                integral multiple of S'Alignment unless specified otherwise by
                a representation item.

26.4/2          {AI95-00291-02} Alignment may be specified for first subtypes
                via an attribute_definition_clause; the expression of such a
                clause shall be static, and its value nonnegative.

26.a/3      Aspect Description for Alignment (subtype): Alignment of a subtype.


                             Erroneous Execution

27  Program execution is erroneous if an Address clause is given that
conflicts with the Alignment.

27.a        Ramification: The user has to either give an Alignment clause
            also, or else know what Alignment the implementation will choose
            by default.

28/2 {AI95-00051-02} {AI95-00291-02} For an object that is not allocated under
control of the implementation, execution is erroneous if the object is not
aligned according to its Alignment.


                            Implementation Advice

28.1/3 {AI05-0116-1} For any tagged specific subtype S, S'Class'Alignment
should equal S'Alignment.

28.a/3      Reason: A tagged object should never be less aligned than the
            alignment of the type of its view, so for a class-wide type
            T'Class, the alignment should be no greater than that of any type
            covered by T'Class. If the implementation only supports alignments
            that are required by the recommended level of support (and this is
            most likely), then the alignment of any covered type has to be the
            same or greater than that of T - which leaves the only reasonable
            value of T'Class'Alignment being T'Alignment. Thus we recommend
            this, but don't require it so that in the unlikely case that the
            implementation does support smaller alignments for covered types,
            it can select a smaller value for T'Class'Alignment.

28.a.1/3    Implementation Advice: For any tagged specific subtype S,
            S'Class'Alignment should equal S'Alignment.

29  The recommended level of support for the Alignment attribute for subtypes
is:

30/2   * {AI95-00051-02} An implementation should support an Alignment clause
        for a discrete type, fixed point type, record type, or array type,
        specifying an Alignment value that is zero or a power of two, subject
        to the following:

31/2   * {AI95-00051-02} An implementation need not support an Alignment
        clause for a signed integer type specifying an Alignment greater than
        the largest Alignment value that is ever chosen by default by the
        implementation for any signed integer type. A corresponding limitation
        may be imposed for modular integer types, fixed point types,
        enumeration types, record types, and array types.

32/2   * {AI95-00051-02} An implementation need not support a nonconfirming
        Alignment clause which could enable the creation of an object of an
        elementary type which cannot be easily loaded and stored by available
        machine instructions.

32.1/2   * {AI95-00291-02} An implementation need not support an Alignment
        specified for a derived tagged type which is not a multiple of the
        Alignment of the parent type. An implementation need not support a
        nonconfirming Alignment specified for a derived untagged by-reference
        type.

32.a/2      Ramification: {AI95-00291-02} There is no recommendation to
            support any nonconfirming Alignment clauses for types not
            mentioned above. Remember that 13.1 requires support for
            confirming Alignment clauses for all types.

32.b/3      Implementation Note: {AI05-0116-1} An implementation that tries to
            support other alignments for derived tagged types will need to
            allow inherited subprograms to be passed objects that are less
            aligned than expected by the parent subprogram and type. This is
            unlikely to work if alignment has any effect on code selection.
            Similar issues arise for untagged derived types whose parameters
            are passed by reference.

33  The recommended level of support for the Alignment attribute for objects
is:

34/2   * This paragraph was deleted.{AI95-00291-02}

35    * For stand-alone library-level objects of statically constrained
        subtypes, the implementation should support all Alignments supported
        by the target linker. For example, page alignment is likely to be
        supported for such objects, but not for subtypes.

35.1/2   * {AI95-00291-02} For other objects, an implementation should at
        least support the alignments supported for their subtype, subject to
        the following:

35.2/2   * {AI95-00291-02} An implementation need not support Alignments
        specified for objects of a by-reference type or for objects of types
        containing aliased subcomponents if the specified Alignment is not a
        multiple of the Alignment of the subtype of the object.

35.a/2      Implementation Advice: The recommended level of support for the
            Alignment attribute should be followed.

        NOTES

36      4  Alignment is a subtype-specific attribute.

37/2    This paragraph was deleted.{AI95-00247-01}

37.a/2      This paragraph was deleted.

38/3    5  {AI05-0229-1} {AI05-0269-1} A component_clause, Component_Size
        clause, or specifying the Pack aspect as True can override a specified
        Alignment.

38.a        Discussion: Most objects are allocated by the implementation; for
            these, the implementation obeys the Alignment. The implementation
            is of course allowed to make an object more aligned than its
            Alignment requires - an object whose Alignment is 4 might just
            happen to land at an address that's a multiple of 4096. For formal
            parameters, the implementation might want to force an Alignment
            stricter than the parameter's subtype. For example, on some
            systems, it is customary to always align parameters to 4 storage
            elements.

38.b        Hence, one might initially assume that the implementation could
            evilly make all Alignments 1 by default, even though integers,
            say, are normally aligned on a 4-storage-element boundary.
            However, the implementation cannot get away with that - if the
            Alignment is 1, the generated code cannot assume an Alignment of
            4, at least not for objects allocated outside the control of the
            implementation.

38.c        Of course implementations can assume anything they can prove, but
            typically an implementation will be unable to prove much about the
            alignment of, say, an imported object. Furthermore, the
            information about where an address "came from" can be lost to the
            compiler due to separate compilation.

38.d/3      {AI95-00114-01} {AI05-0229-1} The Alignment of an object that is a
            component of a packed composite object will usually be 0, to
            indicate that the component is not necessarily aligned on a
            storage element boundary. For a subtype, an Alignment of 0 means
            that objects of the subtype are not normally aligned on a storage
            element boundary at all. For example, an implementation might
            choose to make Component_Size be 1 for an array of Booleans, even
            when the Pack aspect has not been specified for the array. In this
            case, Boolean'Alignment would be 0. (In the presence of tasking,
            this would in general be feasible only on a machine that had
            atomic test-bit and set-bit instructions.)

38.e        If the machine has no particular natural alignments, then all
            subtype Alignments will probably be 1 by default.

38.f        Specifying an Alignment of 0 in an attribute_definition_clause
            does not require the implementation to do anything (except return
            0 when the Alignment is queried). However, it might be taken as
            advice on some implementations.

38.g        It is an error for an Address clause to disobey the object's
            Alignment. The error cannot be detected at compile time, in
            general, because the Address is not necessarily known at compile
            time (and is almost certainly not static). We do not require a
            run-time check, since efficiency seems paramount here, and Address
            clauses are treading on thin ice anyway. Hence, this misuse of
            Address clauses is just like any other misuse of Address clauses -
            it's erroneous.

38.h        A type extension can have a stricter Alignment than its parent.
            This can happen, for example, if the Alignment of the parent is 4,
            but the extension contains a component with Alignment 8. The
            Alignment of a class-wide type or object will have to be the
            maximum possible Alignment of any extension.

38.i        The recommended level of support for the Alignment attribute is
            intended to reflect a minimum useful set of capabilities. An
            implementation can assume that all Alignments are multiples of
            each other - 1, 2, 4, and 8 might be the only supported Alignments
            for subtypes. An Alignment of 3 or 6 is unlikely to be useful. For
            objects that can be allocated statically, we recommend that the
            implementation support larger alignments, such as 4096. We do not
            recommend such large alignments for subtypes, because the maximum
            subtype alignment will also have to be used as the alignment of
            stack frames, heap objects, and class-wide objects. Similarly, we
            do not recommend such large alignments for stack-allocated objects.

38.j        If the maximum default Alignment is 8 (say, Long_Float'Alignment =
            8), then the implementation can refuse to accept stricter
            alignments for subtypes. This simplifies the generated code, since
            the compiler can align the stack and class-wide types to this
            maximum without a substantial waste of space (or time).

38.k        Note that the recommended level of support takes into account
            interactions between Size and Alignment. For example, on a 32-bit
            machine with 8-bit storage elements, where load and store
            instructions have to be aligned according to the size of the thing
            being loaded or stored, the implementation might accept an
            Alignment of 1 if the Size is 8, but might reject an Alignment of
            1 if the Size is 32. On a machine where unaligned loads and stores
            are merely inefficient (as opposed to causing hardware traps), we
            would expect an Alignment of 1 to be supported for any Size.


                         Wording Changes from Ada 83

38.l        The nonnegative part is missing from RM83 (for mod_clauses, nee
            alignment_clauses, which are an obsolete version of Alignment
            clauses).


                              Static Semantics

39/1 For a prefix X that denotes an object:

40  X'Size      Denotes the size in bits of the representation of the object.
                The value of this attribute is of the type universal_integer.

40.a        Ramification: Note that Size is in bits even if Machine_Radix is
            10. Each decimal digit (and the sign) is presumably represented as
            some number of bits.

41              Size may be specified for [stand-alone] objects via an
                attribute_definition_clause; the expression of such a clause
                shall be static and its value nonnegative.

41.a/3      Aspect Description for Size (object): Size in bits of an object.


                            Implementation Advice

41.1/2 {AI95-00051-02} The size of an array object should not include its
bounds.

41.a.1/2    Implementation Advice: The Size of an array object should not
            include its bounds.

42/2 {AI95-00051-02} {AI95-00291-02} The recommended level of support for the
Size attribute of objects is the same as for subtypes (see below), except that
only a confirming Size clause need be supported for an aliased elementary
object.

43/2   * This paragraph was deleted.{AI95-00051-02}


                              Static Semantics

44  For every subtype S:

45  S'Size      If S is definite, denotes the size [(in bits)] that the
                implementation would choose for the following objects of
                subtype S:

46                * A record component of subtype S when the record type is
                    packed.

47                * The formal parameter of an instance of
                    Unchecked_Conversion that converts from subtype S to some
                    other subtype.

48              If S is indefinite, the meaning is implementation defined. The
                value of this attribute is of the type universal_integer. The
                Size of an object is at least as large as that of its subtype,
                unless the object's Size is determined by a Size clause, a
                component_clause, or a Component_Size clause. Size may be
                specified for first subtypes via an attribute_definition_-
                clause; the expression of such a clause shall be static and
                its value nonnegative.

48.a        Implementation defined: The meaning of Size for indefinite
            subtypes.

48.b        Reason: The effects of specifying the Size of a subtype are:

48.c          * Unchecked_Conversion works in a predictable manner.

48.d          * A composite type cannot be packed so tightly as to override
                the specified Size of a component's subtype.

48.e          * Assuming the Implementation Advice is obeyed, if the specified
                Size allows independent addressability, then the Size of
                certain objects of the subtype should be equal to the
                subtype's Size. This applies to stand-alone objects and to
                components (unless a component_clause or a Component_Size
                clause applies).

48.f/3      {AI05-0229-1} A component_clause or a Component_Size clause can
            cause an object to be smaller than its subtype's specified size.
            The aspect Pack cannot; if a component subtype's size is
            specified, this limits how tightly the composite object can be
            packed.

48.g        The Size of a class-wide (tagged) subtype is unspecified, because
            it's not clear what it should mean; it should certainly not depend
            on all of the descendants that happen to exist in a given program.
            Note that this cannot be detected at compile time, because in a
            generic unit, it is not necessarily known whether a given subtype
            is class-wide. It might raise an exception on some
            implementations.

48.h        Ramification: A Size clause for a numeric subtype need not affect
            the underlying numeric type. For example, if I say:

48.i            type S is range 1..2;
                for S'Size use 64;
                  

48.j        I am not guaranteed that S'Base'Last >= 2**63-1, nor that
            intermediate results will be represented in 64 bits.

48.k        Reason: There is no need to complicate implementations for this
            sort of thing, because the right way to affect the base range of a
            type is to use the normal way of declaring the base range:

48.l            type Big is range -2**63 .. 2**63 - 1;
                subtype Small is Big range 1..1000;
                  

48.m        Ramification: The Size of a large unconstrained subtype (e.g.
            String'Size) is likely to raise Constraint_Error, since it is a
            nonstatic expression of type universal_integer that might overflow
            the largest signed integer type. There is no requirement that the
            largest integer type be able to represent the size in bits of the
            largest possible object.

48.n/3      Aspect Description for Size (subtype): Size in bits of a subtype.


                         Implementation Requirements

49  In an implementation, Boolean'Size shall be 1.


                            Implementation Advice

50/2 {AI95-00051-02} If the Size of a subtype allows for efficient independent
addressability (see 9.10) on the target architecture, then the Size of the
following objects of the subtype should equal the Size of the subtype:

51    * Aliased objects (including components).

52    * Unaliased components, unless the Size of the component is determined
        by a component_clause or Component_Size clause.

52.a.1/2    Implementation Advice: If the Size of a subtype allows for
            efficient independent addressability, then the Size of most
            objects of the subtype should equal the Size of the subtype.

52.a        Ramification: Thus, on a typical 32-bit machine, "for S'Size use
            32;" will guarantee that aliased objects of subtype S, and
            components whose subtype is S, will have Size = 32 (assuming the
            implementation chooses to obey this Implementation Advice). On the
            other hand, if one writes, "for S2'Size use 5;" then stand-alone
            objects of subtype S2 will typically have their Size rounded up to
            ensure independent addressability.

52.b        Note that "for S'Size use 32;" does not cause things like formal
            parameters to have Size = 32 - the implementation is allowed to
            make all parameters be at least 64 bits, for example.

52.c        Note that "for S2'Size use 5;" requires record components whose
            subtype is S2 to be exactly 5 bits if the record type is packed.
            The same is not true of array components; their Size may be
            rounded up to the nearest factor of the word size.

52.d/2      Implementation Note: {AI95-00291-02} On most machines, arrays
            don't contain gaps between elementary components; if the
            Component_Size is greater than the Size of the component subtype,
            the extra bits are generally considered part of each component,
            rather than gaps between components. On the other hand, a record
            might contain gaps between elementary components, depending on
            what sorts of loads, stores, and masking operations are generally
            done by the generated code.

52.e/2      {AI95-00291-02} For an array, any extra bits stored for each
            elementary component will generally be part of the component - the
            whole point of storing extra bits is to make loads and stores more
            efficient by avoiding the need to mask out extra bits. The PDP-10
            is one counter-example; since the hardware supports byte strings
            with a gap at the end of each word, one would want to pack in that
            manner.

53  A Size clause on a composite subtype should not affect the internal layout
of components.

53.a.1/2    Implementation Advice: A Size clause on a composite subtype should
            not affect the internal layout of components.

53.a/3      Reason: {AI05-0229-1} That's what Pack aspects,
            record_representation_clauses, and Component_Size clauses are for.

54  The recommended level of support for the Size attribute of subtypes is:

55    * The Size (if not specified) of a static discrete or fixed point
        subtype should be the number of bits needed to represent each value
        belonging to the subtype using an unbiased representation, leaving
        space for a sign bit only if the subtype contains negative values. If
        such a subtype is a first subtype, then an implementation should
        support a specified Size for it that reflects this representation.

55.a        Implementation Note: This applies to static enumeration subtypes,
            using the internal codes used to represent the values.

55.b        For a two's-complement machine, this implies that for a static
            signed integer subtype S, if all values of S are in the range 0 ..
            2(n)-1, or all values of S are in the range -2(n-1) .. 2(n-1)-1,
            for some n less than or equal to the word size, then S'Size should
            be <= the smallest such n. For a one's-complement machine, it is
            the same except that in the second range, the lower bound "
            -2(n-1)" is replaced by "-2(n-1)+1".

55.c        If an integer subtype (whether signed or unsigned) contains no
            negative values, the Size should not include space for a sign bit.

55.d        Typically, the implementation will choose to make the Size of a
            subtype be exactly the smallest such n. However, it might, for
            example, choose a biased representation, in which case it could
            choose a smaller value.

55.e/3      {AI05-0229-1} On most machines, it is in general not a good idea
            to pack (parts of) multiple stand-alone objects into the same
            storage element, because (1) it usually doesn't save much space,
            and (2) it requires locking to prevent tasks from interfering with
            each other, since separate stand-alone objects are independently
            addressable. Therefore, if S'Size = 2 on a machine with 8-bit
            storage elements, the size of a stand-alone object of subtype S
            will probably not be 2. It might, for example, be 8, 16 or 32,
            depending on the availability and efficiency of various machine
            instructions. The same applies to components of composite types,
            unless Pack, Component_Size, or record layout is specified.

55.f        For an unconstrained discriminated object, if the implementation
            allocates the maximum possible size, then the Size attribute
            should return that maximum possible size.

55.g        Ramification: The Size of an object X is not usually the same as
            that of its subtype S. If X is a stand-alone object or a
            parameter, for example, most implementations will round X'Size up
            to a storage element boundary, or more, so X'Size might be greater
            than S'Size. On the other hand, X'Size cannot be less than S'Size,
            even if the implementation can prove, for example, that the range
            of values actually taken on by X during execution is smaller than
            the range of S.

55.h        For example, if S is a first integer subtype whose range is 0..3,
            S'Size will be probably be 2 bits, and components of packed
            composite types of this subtype will be 2 bits (assuming
            Storage_Unit is a multiple of 2), but stand-alone objects and
            parameters will probably not have a size of 2 bits; they might be
            rounded up to 32 bits, for example. On the other hand,
            Unchecked_Conversion will use the 2-bit size, even when converting
            a stand-alone object, as one would expect.

55.i        Another reason for making the Size of an object bigger than its
            subtype's Size is to support the run-time detection of
            uninitialized variables. The implementation might add an extra
            value to a discrete subtype that represents the uninitialized
            state, and check for this value on use. In some cases, the extra
            value will require an extra bit in the representation of the
            object. Such detection is not required by the language. If it is
            provided, the implementation has to be able to turn it off. For
            example, if the programmer gives a record_representation_clause or
            Component_Size clause that makes a component too small to allow
            the extra bit, then the implementation will not be able to perform
            the checking (not using this method, anyway).

55.j        The fact that the size of an object is not necessarily the same as
            its subtype can be confusing:

55.k            type Device_Register is range 0..2**8 - 1;
                for Device_Register'Size use 8; -- Confusing!
                My_Device : Device_Register;
                for My_Device'Address use To_Address(16#FF00#);
                  

55.l        The programmer might think that My_Device'Size is 8, and that
            My_Device'Address points at an 8-bit location. However, this is
            not true. In Ada 83 (and in Ada 95), My_Device'Size might well be
            32, and My_Device'Address might well point at the high-order 8
            bits of the 32-bit object, which are always all zero bits. If
            My_Device'Address is passed to an assembly language subprogram,
            based on the programmer's assumption, the program will not work
            properly.

55.m        Reason: It is not reasonable to require that an implementation
            allocate exactly 8 bits to all objects of subtype Device_Register.
            For example, in many run-time models, stand-alone objects and
            parameters are always aligned to a word boundary. Such run-time
            models are generally based on hardware considerations that are
            beyond the control of the implementer. (It is reasonable to
            require that an implementation allocate exactly 8 bits to all
            components of subtype Device_Register, if packed.)

55.n        Ramification: The correct way to write the above code is like
            this:

55.o            type Device_Register is range 0..2**8 - 1;
                My_Device : Device_Register;
                for My_Device'Size use 8;
                for My_Device'Address use To_Address(16#FF00#);
                  

55.p        If the implementation cannot accept 8-bit stand-alone objects,
            then this will be illegal. However, on a machine where an 8-bit
            device register exists, the implementation will probably be able
            to accept 8-bit stand-alone objects. Therefore, My_Device'Size
            will be 8, and My_Device'Address will point at those 8 bits, as
            desired.

55.q        If an object of subtype Device_Register is passed to a foreign
            language subprogram, it will be passed according to that
            subprogram's conventions. Most foreign language implementations
            have similar run-time model restrictions. For example, when
            passing to a C function, where the argument is of the C type char*
            (that is, pointer to char), the C compiler will generally expect a
            full word value, either on the stack, or in a register. It will
            not expect a single byte. Thus, Size clauses for subtypes really
            have nothing to do with passing parameters to foreign language
            subprograms.

56    * For a subtype implemented with levels of indirection, the Size should
        include the size of the pointers, but not the size of what they point
        at.

56.a        Ramification: For example, if a task object is represented as a
            pointer to some information (including a task stack), then the
            size of the object should be the size of the pointer. The
            Storage_Size, on the other hand, should include the size of the
            stack.

56.1/2   * {AI95-00051-02} An implementation should support a Size clause for
        a discrete type, fixed point type, record type, or array type, subject
        to the following:

56.2/2    * {AI95-00051-02} An implementation need not support a Size clause
            for a signed integer type specifying a Size greater than that of
            the largest signed integer type supported by the implementation in
            the absence of a size clause (that is, when the size is chosen by
            default). A corresponding limitation may be imposed for modular
            integer types, fixed point types, enumeration types, record types,
            and array types.

56.b/2      Discussion: {AI95-00051-02} Note that the "corresponding
            limitation" for a record or array type implies that an implementation may
            impose some reasonable maximum size for records and arrays (e.g.
            2**32 bits), which is an upper bound ("capacity" limit) on the
            size, whether chosen by default or by being specified by the user.
            The largest size supported for records need not be the same as the
            largest size supported for arrays.

56.b.1/3    Ramification: {AI05-0155-1} Only Size clauses with a size greater
            than or equal to the Size that would be chosen by default may be
            safely presumed to be supported on nonstatic elementary subtypes.
            Implementations may choose to support smaller sizes, but only if
            the Size allows any value of the subtype to be represented, for
            any possible value of the bounds.

56.3/2    * {AI95-00291-02} A nonconfirming size clause for the first subtype
            of a derived untagged by-reference type need not be supported.

56.c/2      Implementation Advice: The recommended level of support for the
            Size attribute should be followed.

56.d/2      Ramification: {AI95-00291-02} There is no recommendation to
            support any nonconfirming Size clauses for types not mentioned
            above. Remember that 13.1 requires support for confirming Size
            clauses for all types.

        NOTES

57      6  Size is a subtype-specific attribute.

58/3    7  {AI05-0229-1} A component_clause or Component_Size clause can
        override a specified Size. Aspect Pack cannot.


                         Inconsistencies With Ada 83

58.a.1/2    {AI95-00114-01} We specify the meaning of Size in much more detail
            than Ada 83. This is not technically an inconsistency, but it is
            in practice, as most Ada 83 compilers use a different definition
            for Size than is required here. This should have been documented
            more explicitly during the Ada 9X process.


                         Wording Changes from Ada 83

58.a        The requirement for a nonnegative value in a Size clause was not
            in RM83, but it's hard to see how it would make sense. For
            uniformity, we forbid negative sizes, rather than letting
            implementations define their meaning.


                              Static Semantics

59/1 For a prefix T that denotes a task object [(after any implicit
dereference)]:

60/3 T'Storage_Size
                {AI05-0229-1} Denotes the number of storage elements reserved
                for the task. The value of this attribute is of the type
                universal_integer. The Storage_Size includes the size of the
                task's stack, if any. The language does not specify whether or
                not it includes other storage associated with the task (such
                as the "task control block" used by some implementations.) If
                the aspect Storage_Size is specified for the type of the
                object, the value of the Storage_Size attribute is at least
                the value determined by the aspect.

60.a        Ramification: The value of this attribute is never negative, since
            it is impossible to "reserve" a negative number of storage
            elements.

60.b        If the implementation chooses to allocate an initial amount of
            storage, and then increase this as needed, the Storage_Size cannot
            include the additional amounts (assuming the allocation of the
            additional amounts can raise Storage_Error); this is inherent in
            the meaning of "reserved."

60.c        The implementation is allowed to allocate different amounts of
            storage for different tasks of the same subtype.

60.d        Storage_Size is also defined for access subtypes - see 13.11.

61/3 {AI95-0229-1} [Aspect Storage_Size specifies the amount of storage to be
reserved for the execution of a task.]

Paragraphs 62 through 65 were moved to Annex J, "Obsolescent Features".


                              Static Semantics

65.1/3 {AI05-0229-1} {AI05-0269-1} For a task type (including the anonymous
type of a single_task_declaration), the following language-defined
representation aspect may be specified:

65.2/3 Storage_Size
                The Storage_Size aspect is an expression, which shall be of
                any integer type.

65.a/3      To be honest: This definition somewhat conflicts with the
            "automatic" one for the obsolescent attribute Storage_Size (which
            can be specified). The only difference is where the given
            expression is evaluated. We intend for the above definition to
            supersede that "automatic" definition for this attribute.

65.b/3      Ramification: Note that the value of the Storage_Size aspect is an
            expression; it is not the value of an expression. The expression
            is evaluated for each object of the type (see below).

65.c/3      Aspect Description for Storage_Size (task): Size in storage
            elements reserved for a task type or single task object.


                               Legality Rules

65.3/3 {AI05-0229-1} The Storage_Size aspect shall not be specified for a task
interface type.


                              Dynamic Semantics

66/3 {AI05-0229-1} When a task object is created, the expression (if any)
associated with the Storage_Size aspect of its type is evaluated; the
Storage_Size attribute of the newly created task object is at least the value
of the expression.

66.a        Ramification: The implementation is allowed to round up a
            specified Storage_Size amount. For example, if the implementation
            always allocates in chunks of 4096 bytes, the number 200 might be
            rounded up to 4096. Also, if the user specifies a negative number,
            the implementation has to normalize this to 0, or perhaps to a
            positive number.

66.b/3      {AI05-0229-1} If the Storage_Size aspect is not specified for the
            type of the task object, the value of the Storage_Size attribute
            is unspecified.

67  At the point of task object creation, or upon task activation,
Storage_Error is raised if there is insufficient free storage to accommodate
the requested Storage_Size.


                              Static Semantics

68/1 For a prefix X that denotes an array subtype or array object [(after any
implicit dereference)]:

69  X'Component_Size
                Denotes the size in bits of components of the type of X. The
                value of this attribute is of type universal_integer.

70              Component_Size may be specified for array types via an
                attribute_definition_clause; the expression of such a clause
                shall be static, and its value nonnegative.

70.a        Implementation Note: The intent is that the value of
            X'Component_Size is always nonnegative. If the array is stored "
            backwards" in memory (which might be caused by an
            implementation-defined pragma), X'Component_Size is still
            positive.

70.b        Ramification: For an array object A, A'Component_Size = A(I)'Size
            for any index I.

70.c/3      Aspect Description for Component_Size: Size in bits of a component
            of an array type.


                            Implementation Advice

71  The recommended level of support for the Component_Size attribute is:

72    * An implementation need not support specified Component_Sizes that are
        less than the Size of the component subtype.

73/3   * {AI05-0229-1} An implementation should support specified
        Component_Sizes that are factors and multiples of the word size. For
        such Component_Sizes, the array should contain no gaps between
        components. For other Component_Sizes (if supported), the array should
        contain no gaps between components when Pack is also specified; the
        implementation should forbid this combination in cases where it cannot
        support a no-gaps representation.

73.a/3      Ramification: {AI05-0229-1} For example, if Storage_Unit = 8, and
            Word_Size = 32, then the user is allowed to specify a
            Component_Size of 1, 2, 4, 8, 16, and 32, with no gaps. In
            addition, n*32 is allowed for positive integers n, again with no
            gaps. If the implementation accepts Component_Size = 3, then it
            might allocate 10 components per word, with a 2-bit gap at the end
            of each word (unless Pack is also specified), or it might not have
            any internal gaps at all. (There can be gaps at either end of the
            array.)

73.b/2      Implementation Advice: The recommended level of support for the
            Component_Size attribute should be followed.


                              Static Semantics

73.1/3 {AI05-0191-1} For a prefix X that denotes an object:

73.2/4 X'Has_Same_Storage
                {AI05-0191-1} X'Has_Same_Storage denotes a function with the
                following specification:

73.3/3              function X'Has_Same_Storage (Arg : any_type)
                      return Boolean

73.4/4          {AI05-0191-1} {AI05-0264-1} {AI12-0077-1} The actual parameter
                shall be a name that denotes an object. The object denoted by
                the actual parameter can be of any type. This function
                evaluates the names of the objects involved. It returns True
                if the representation of the object denoted by the actual
                parameter occupies exactly the same bits as the representation
                of the object denoted by X and the objects occupy at least one
                bit; otherwise, it returns False.

73.c/3      Discussion: Has_Same_Storage means that, if the representation is
            contiguous, the objects sit at the same address and occupy the
            same length of memory.

73.5/3 {AI05-0191-1} For a prefix X that denotes an object:

73.6/3 X'Overlaps_Storage
                {AI05-0191-1} X'Overlaps_Storage denotes a function with the
                following specification:

73.7/3              function X'Overlaps_Storage (Arg : any_type)
                      return Boolean

73.8/3          {AI05-0191-1} {AI05-0264-1} The actual parameter shall be a
                name that denotes an object. The object denoted by the actual
                parameter can be of any type. This function evaluates the
                names of the objects involved and returns True if the
                representation of the object denoted by the actual parameter
                shares at least one bit with the representation of the object
                denoted by X; otherwise, it returns False.

        NOTES

73.9/3  8  {AI05-0191-1} X'Has_Same_Storage(Y) implies X'Overlaps_Storage(Y).

73.10/3 9  {AI05-0191-1} X'Has_Same_Storage(Y) and X'Overlaps_Storage(Y) are
        not considered to be reads of X and Y.


                              Static Semantics

73.11/3 {8652/0009} {AI95-00137-01} {AI05-0183-1} The following type-related
operational attribute is defined: External_Tag.

74/1 {8652/0009} {AI95-00137-01} For every subtype S of a tagged type T
(specific or class-wide):

75/3 S'External_Tag
                {8652/0040} {AI95-00108-01} {AI05-0092-1} S'External_Tag
                denotes an external string representation for S'Tag; it is of
                the predefined type String. External_Tag may be specified for
                a specific tagged type via an attribute_definition_clause; the
                expression of such a clause shall be static. The default
                external tag representation is implementation defined. See
                13.13.2. The value of External_Tag is never inherited[; the
                default value is always used unless a new value is directly
                specified for a type].

75.a        Implementation defined: The default external representation for a
            type tag.

75.b/3      Aspect Description for External_Tag: Unique identifier for a
            tagged type in streams.


                              Dynamic Semantics

75.1/3 {AI05-0113-1} If a user-specified external tag S'External_Tag is the
same as T'External_Tag for some other tagged type declared by a different
declaration in the partition, Program_Error is raised by the elaboration of
the attribute_definition_clause.

75.c/3      Ramification: This rule does not depend on the visibility of the
            other tagged type, but it does depend on the existence of the
            other tagged type. The other tagged type could have the default
            external tag or a user-specified external tag.

75.d/3      This rule allows the same declaration to be elaborated multiple
            times. In that case, different types could have the same external
            tag. If that happens, Internal_Tag would return some unspecified
            tag, and Descendant_Tag probably would return the intended tag
            (using the given ancestor to determine which type is intended).
            However, in some cases (such as multiple instantiations of a
            derived tagged type declared in a generic body), Tag_Error might
            be raised by Descendant_Tag if multiple types are identified.

75.e/3      Note that while there is a race condition inherent in this
            definition (which attribute_definition_clause raises Program_Error
            depends on the order of elaboration), it doesn't matter as a
            program with two such clauses is simply wrong. Two types that both
            come from the same declaration are allowed, as noted previously.


                         Implementation Requirements

76  In an implementation, the default external tag for each specific tagged
type declared in a partition shall be distinct, so long as the type is
declared outside an instance of a generic body. If the compilation unit in
which a given tagged type is declared, and all compilation units on which it
semantically depends, are the same in two different partitions, then the
external tag for the type shall be the same in the two partitions. What it
means for a compilation unit to be the same in two different partitions is
implementation defined. At a minimum, if the compilation unit is not
recompiled between building the two different partitions that include it, the
compilation unit is considered the same in the two partitions.

76.a        Implementation defined: What determines whether a compilation unit
            is the same in two different partitions.

76.b        Reason: These requirements are important because external tags are
            used for input/output of class-wide types. These requirements
            ensure that what is written by one program can be read back by
            some other program so long as they share the same declaration for
            the type (and everything it depends on).

76.c        The user may specify the external tag if (s)he wishes its value to
            be stable even across changes to the compilation unit in which the
            type is declared (or changes in some unit on which it depends).

76.d/2      {AI95-00114-01} We use a String rather than a Stream_Element_Array
            to represent an external tag for portability.

76.e        Ramification: Note that the characters of an external tag need not
            all be graphic characters. In other words, the external tag can be
            a sequence of arbitrary 8-bit bytes.


                         Implementation Permissions

76.1/3 {AI05-0113-1} If a user-specified external tag S'External_Tag is the
same as T'External_Tag for some other tagged type declared by a different
declaration in the partition, the partition may be rejected.

76.f/3      Ramification: This is, in general, a post-compilation check. This
            permission is intended for implementations that do link-time
            construction of the external tag lookup table; implementations
            that dynamically construct the table will likely prefer to raise
            Program_Error upon elaboration of the problem construct. We don't
            want this check to require any implementation complexity, as it
            will be very rare that there would be a problem.

        NOTES

77/2    10  {AI95-00270-01} The following language-defined attributes are
        specifiable, at least for some of the kinds of entities to which they
        apply: Address, Alignment, Bit_Order, Component_Size, External_Tag,
        Input, Machine_Radix, Output, Read, Size, Small, Storage_Pool,
        Storage_Size, Stream_Size, and Write.

78      11  It follows from the general rules in 13.1 that if one writes "for
        X'Size use Y;" then the X'Size attribute_reference will return Y
        (assuming the implementation allows the Size clause). The same is true
        for all of the specifiable attributes except Storage_Size.

78.a        Ramification: An implementation may specify that an
            implementation-defined attribute is specifiable for certain
            entities. This follows from the fact that the semantics of
            implementation-defined attributes is implementation defined. An
            implementation is not allowed to make a language-defined attribute
            specifiable if it isn't.


                                  Examples

79  Examples of attribute definition clauses:

80      Byte : constant := 8;
        Page : constant := 2**12;

81      type Medium is range 0 .. 65_000;
        for Medium'Size use 2*Byte;
        for Medium'Alignment use 2;
        Device_Register : Medium;
        for Device_Register'Size use Medium'Size;
        for Device_Register'Address use System.Storage_Elements.To_Address(16#FFFF_0020#);

82      type Short is delta 0.01 range -100.0 .. 100.0;
        for Short'Size use 15;

83      for Car_Name'Storage_Size use -- specify access type's storage pool size
                2000*((Car'Size/System.Storage_Unit) +1); -- approximately 2000 cars

84/2    {AI95-00441-01}
        function My_Input(Stream : not null access Ada.Streams.Root_Stream_Type'Class)
          return T;
        for T'Input use My_Input; -- see 13.13.2

        NOTES

85      12  Notes on the examples: In the Size clause for Short, fifteen bits
        is the minimum necessary, since the type definition requires
        Short'Small <= 2**(-7).


                            Extensions to Ada 83

85.a        The syntax rule for length_clause is replaced with the new syntax
            rule for attribute_definition_clause, and it is modified to allow
            a name (as well as an expression).


                         Wording Changes from Ada 83

85.b        The syntax rule for attribute_definition_clause now requires that
            the prefix of the attribute be a local_name; in Ada 83 this rule
            was stated in the text.

85.c/2      {AI95-00114-01} In Ada 83, the relationship between a
            aspect_clause specifying a certain aspect and an attribute that
            queried that aspect was unclear. In Ada 95, they are the same,
            except for certain explicit exceptions.


                         Wording Changes from Ada 95

85.d/2      {8652/0009} {AI95-00137-01} Corrigendum: Added wording to specify
            for each attribute whether it is an operational or representation
            attribute.

85.e/2      {8652/0040} {AI95-00108-01} Corrigendum: Added wording to specify
            that External_Tag is never inherited.

85.f/2      {AI95-00051-01} {AI95-00291-01} Adjusted the Recommended Level of
            Support for Alignment to eliminate nonsense requirements and to
            ensure that useful capabilities are required.

85.g/2      {AI95-00051-01} {AI95-00291-01} Adjusted the Recommended Level of
            Support for Size to eliminate nonsense requirements and to ensure
            that useful capabilities are required. Also eliminated any
            dependence on whether an aspect was specified (a confirming
            representation item should not affect the semantics).

85.h/2      {AI95-00133-01} Added the definition of machine scalar.

85.i/2      {AI95-00247-01} Removed the requirement that specified alignments
            for a composite type cannot override those for their components,
            because it was never intended to apply to components whose
            location was specified with a representation item. Moreover, it
            causes a difference in legality when a confirming alignment is
            specified for one of the composite types.

85.j/2      {AI95-00291-02} Removed recommended level of support rules about
            types with by-reference and aliased parts, because there are now
            blanket rules covering all recommended level of support rules.

85.k/2      {AI95-00291-02} Split the definition of Alignment for subtypes and
            for objects. This simplified the wording and eliminated confusion
            about which rules applied to objects, which applied to subtypes,
            and which applied to both.


                        Inconsistencies With Ada 2005

85.l/3      {AI95-0095-1} Correction: An address attribute with a prefix of a
            generic formal subprogram whose actual parameter has convention
            Intrinsic now raises Program_Error. Since it is unlikely that such
            an attribute would have done anything useful (a subprogram with
            convention Intrinsic is not expected to have a normal subprogram
            body), it is highly unlikely that any existing programs would
            notice the difference, and any that do probably are buggy.

85.m/3      {AI95-0113-1} Correction: User-specified external tags that
            conflict with other external tags raise Program_Error (or are
            optionally illegal). This was legal and did not raise an exception
            in the past, although the effects were not defined. So while a
            program might depend on such behavior, the results were not
            portable (even to different versions of the same implementation).
            Such programs should be rare.


                       Incompatibilities With Ada 2005

85.n/3      {AI05-0095-1} Correction: An address attribute with a prefix of a
            subprogram with convention Intrinsic is now illegal. Such
            attributes are very unlikely to have provided a useful answer (the
            intended meaning of convention Intrinsic is that there is no
            actual subprogram body for the operation), so this is highly
            unlikely to affect any existing programs unless they have a hidden
            bug.


                           Extensions to Ada 2005

85.o/3      {AI05-0191-1} Attributes Has_Same_Storage and Overlaps_Storage are
            new.

85.p/3      {AI05-0229-1} Aspect Storage_Size is new; pragma Storage_Size is
            now obsolescent, joining attribute Storage_Size for task types.


                        Wording Changes from Ada 2005

85.q/3      {AI05-0009-1} Correction: Improved the description of erroneous
            execution for address clauses to make it clear that specifying an
            address inappropriate for the entity will lead to erroneous
            execution.

85.r/3      {AI05-0116-1} Correction: Added Implementation Advice for the
            alignment of class-wide types.


                        Wording Changes from Ada 2012

85.s/4      {AI12-0070-1} Corrigendum: Clarified the behavior of
            Has_Same_Storage when 'Size = 0.


13.4 Enumeration Representation Clauses


1   [An enumeration_representation_clause specifies the internal codes for
enumeration literals.]


                                   Syntax

2       enumeration_representation_clause ::= 
            for first_subtype_local_name use enumeration_aggregate;

3       enumeration_aggregate ::= array_aggregate


                            Name Resolution Rules

4   The enumeration_aggregate shall be written as a one-dimensional
array_aggregate, for which the index subtype is the unconstrained subtype of
the enumeration type, and each component expression is expected to be of any
integer type.

4.a         Ramification: The "full coverage rules" for aggregates applies. An
            others is not allowed - there is no applicable index constraint in
            this context.


                               Legality Rules

5   The first_subtype_local_name of an enumeration_representation_clause shall
denote an enumeration subtype.

5.a         Ramification: As for all type-related representation items, the
            local_name is required to denote a first subtype.

6/2 {AI95-00287-01} Each component of the array_aggregate shall be given by an
expression rather than a <>. The expressions given in the array_aggregate
shall be static, and shall specify distinct integer codes for each value of
the enumeration type; the associated integer codes shall satisfy the
predefined ordering relation of the type.

6.a         Reason: Each value of the enumeration type has to be given an
            internal code, even if the first subtype of the enumeration type
            is constrained to only a subrange (this is only possible if the
            enumeration type is a derived type). This "full coverage"
            requirement is important because one may refer to Enum'Base'First
            and Enum'Base'Last, which need to have defined representations.


                              Static Semantics

7   An enumeration_representation_clause specifies the coding aspect of
representation. The coding consists of the internal code for each enumeration
literal, that is, the integral value used internally to represent each literal.

7.a/3       Aspect Description for Coding: Internal representation of
            enumeration literals. Specified by an
            enumeration_representation_clause, not by an
            aspect_specification.


                         Implementation Requirements

8   For nonboolean enumeration types, if the coding is not specified for the
type, then for each value of the type, the internal code shall be equal to its
position number.

8.a         Reason: This default representation is already used by all known
            Ada compilers for nonboolean enumeration types. Therefore, we make
            it a requirement so users can depend on it, rather than feeling
            obliged to supply for every enumeration type an enumeration
            representation clause that is equivalent to this default rule.

8.b         Discussion: For boolean types, it is relatively common to use all
            ones for True, and all zeros for False, since some hardware
            supports that directly. Of course, for a one-bit Boolean object
            (like in a packed array), False is presumably zero and True is
            presumably one (choosing the reverse would be extremely
            unfriendly!).


                            Implementation Advice

9   The recommended level of support for enumeration_representation_clauses
is:

10    * An implementation should support at least the internal codes in the
        range System.Min_Int..System.Max_Int. An implementation need not
        support enumeration_representation_clauses for boolean types.

10.a        Ramification: The implementation may support numbers outside the
            above range, such as numbers greater than System.Max_Int. See
            AI83-00564.

10.b        Reason: The benefits of specifying the internal coding of a
            boolean type do not outweigh the implementation costs. Consider,
            for example, the implementation of the logical operators on a
            packed array of booleans with strange internal codes. It's
            implementable, but not worth it.

10.c/2      Implementation Advice: The recommended level of support for
            enumeration_representation_clauses should be followed.

        NOTES

11/3    13  {8652/0009} {AI95-00137-01} {AI05-0299-1} Unchecked_Conversion may
        be used to query the internal codes used for an enumeration type. The
        attributes of the type, such as Succ, Pred, and Pos, are unaffected by
        the enumeration_representation_clause. For example, Pos always returns
        the position number, not the internal integer code that might have
        been specified in an enumeration_representation_clause.

11.a        Discussion: Suppose the enumeration type in question is derived:

11.b            type T1 is (Red, Green, Blue);
                subtype S1 is T1 range Red .. Green;
                type S2 is new S1;
                for S2 use (Red => 10, Green => 20, Blue => 30);

11.c/1      {8652/0009} {AI95-00137-01} The
            enumeration_representation_clause has to specify values for all
            enumerals, even ones that are not in S2 (such as Blue). The Base
            attribute can be used to get at these values. For example:

11.d            for I in S2'Base loop
                    ... -- When I equals Blue, the internal code is 30.
                end loop;

11.e        We considered allowing or requiring "for S2'Base use ..." in cases
            like this, but it didn't seem worth the trouble.


                                  Examples

12  Example of an enumeration representation clause:

13      type Mix_Code is (ADD, SUB, MUL, LDA, STA, STZ);

14      for Mix_Code use
           (ADD => 1, SUB => 2, MUL => 3, LDA => 8, STA => 24, STZ =>33);


                            Extensions to Ada 83

14.a        As in other similar contexts, Ada 95 allows expressions of any
            integer type, not just expressions of type universal_integer, for
            the component expressions in the enumeration_aggregate. The
            preference rules for the predefined operators of root_integer
            eliminate any ambiguity.

14.b        For portability, we now require that the default coding for an
            enumeration type be the "obvious" coding using position numbers.
            This is satisfied by all known implementations.


                         Wording Changes from Ada 95

14.c/2      {8652/0009} {AI95-00137-01} Corrigendum: Updated to reflect that
            we no longer have something called representation_clause.

14.d/2      {AI95-00287-01} Added wording to prevent the use of <> in a
            enumeration_representation_clause. (<> is newly added to
            array_aggregates.)


13.5 Record Layout


1   The (record) layout aspect of representation consists of the storage
places for some or all components, that is, storage place attributes of the
components. The layout can be specified with a record_representation_clause.


13.5.1 Record Representation Clauses


1   [A record_representation_clause specifies the storage representation of
records and record extensions, that is, the order, position, and size of
components (including discriminants, if any). ]


                         Language Design Principles

1.a/2       {AI95-00114-01} It should be feasible for an implementation to use
            negative offsets in the representation of composite types.
            However, no implementation should be forced to support negative
            offsets. Therefore, in the interest of uniformity, negative
            offsets should be disallowed in record_representation_clauses.


                                   Syntax

2       record_representation_clause ::= 
            for first_subtype_local_name use
              record [mod_clause]
                {component_clause}
              end record;

3       component_clause ::= 
            component_local_name at position range first_bit .. last_bit;

4       position ::= static_expression

5       first_bit ::= static_simple_expression

6       last_bit ::= static_simple_expression

6.a         Reason: First_bit and last_bit need to be simple_expression
            instead of expression for the same reason as in range (see 3.5
            , "Scalar Types").


                            Name Resolution Rules

7   Each position, first_bit, and last_bit is expected to be of any integer
type.

7.a         Ramification: These need not have the same integer type.


                               Legality Rules

8/2 {AI95-00436-01} The first_subtype_local_name of a
record_representation_clause shall denote a specific record or record
extension subtype.

8.a         Ramification: As for all type-related representation items, the
            local_name is required to denote a first subtype.

9   If the component_local_name is a direct_name, the local_name shall denote
a component of the type. For a record extension, the component shall not be
inherited, and shall not be a discriminant that corresponds to a discriminant
of the parent type. If the component_local_name has an attribute_designator,
the direct_name of the local_name shall denote either the declaration of the
type or a component of the type, and the attribute_designator shall denote an
implementation-defined implicit component of the type.

10  The position, first_bit, and last_bit shall be static expressions. The
value of position and first_bit shall be nonnegative. The value of last_bit
shall be no less than first_bit - 1.

10.a        Ramification: A component_clause such as "X at 4 range 0..-1;" is
            allowed if X can fit in zero bits.

10.1/2 {AI95-00133-01} If the nondefault bit ordering applies to the type,
then either:

10.2/2   * the value of last_bit shall be less than the size of the largest
        machine scalar; or

10.3/2   * the value of first_bit shall be zero and the value of last_bit + 1
        shall be a multiple of System.Storage_Unit.

11  At most one component_clause is allowed for each component of the type,
including for each discriminant (component_clauses may be given for some, all,
or none of the components). Storage places within a component_list shall not
overlap, unless they are for components in distinct variants of the same
variant_part.

12  A name that denotes a component of a type is not allowed within a
record_representation_clause for the type, except as the
component_local_name of a component_clause.

12.a        Reason: It might seem strange to make the
            record_representation_clause part of the declarative region, and
            then disallow mentions of the components within almost all of the
            record_representation_clause. The alternative would be to treat
            the component_local_name like a formal parameter name in a
            subprogram call (in terms of visibility). However, this rule would
            imply slightly different semantics, because (given the actual
            rule) the components can hide other declarations. This was the
            rule in Ada 83, and we see no reason to change it. The following,
            for example, was and is illegal:

12.b            type T is
                    record
                        X : Integer;
                    end record;
                X : constant := 31; -- Same defining name as the component.
                for T use
                    record
                        X at 0 range 0..X; -- Illegal!
                    end record;
                    

12.c        The component X hides the named number X throughout the
            record_representation_clause.


                              Static Semantics

13/2 {AI95-00133-01} A record_representation_clause (without the mod_clause)
specifies the layout.

13.a/3      Aspect Description for Layout (record): Layout of record
            components. Specified by a record_representation_clause, not by an
            aspect_specification.

13.b/3      Aspect Description for Record layout: See Layout.

13.1/2 {AI95-00133-01} If the default bit ordering applies to the type, the
position, first_bit, and last_bit of each component_clause directly specify
the position and size of the corresponding component.

13.2/3 {AI95-00133-01} {AI05-0264-1} If the nondefault bit ordering applies to
the type, then the layout is determined as follows:

13.3/2   * the component_clauses for which the value of last_bit is greater
        than or equal to the size of the largest machine scalar directly
        specify the position and size of the corresponding component;

13.4/2   * for other component_clauses, all of the components having the same
        value of position are considered to be part of a single machine
        scalar, located at that position; this machine scalar has a size which
        is the smallest machine scalar size larger than the largest last_bit
        for all component_clauses at that position; the first_bit and
        last_bit of each component_clause are then interpreted as bit offsets
        in this machine scalar.

13.c/2      This paragraph was deleted.{AI95-00133-01}

13.d        Ramification: A component_clause also determines the value of the
            Size attribute of the component, since this attribute is related
            to First_Bit and Last_Bit.

14  [A record_representation_clause for a record extension does not override
the layout of the parent part;] if the layout was specified for the parent
type, it is inherited by the record extension.


                         Implementation Permissions

15  An implementation may generate implementation-defined components (for
example, one containing the offset of another component). An implementation
may generate names that denote such implementation-defined components; such
names shall be implementation-defined attribute_references. An implemen-
tation may allow such implementation-defined names to be used in record_-
representation_clauses. An implementation can restrict such component_clauses
in any manner it sees fit.

15.a        Implementation defined: Implementation-defined components.

15.b        Ramification: Of course, since the semantics of
            implementation-defined attributes is implementation defined, the
            implementation need not support these names in all situations.
            They might be purely for the purpose of component_clauses, for
            example. The visibility rules for such names are up to the
            implementation.

15.c        We do not allow such component names to be normal identifiers -
            that would constitute blanket permission to do all kinds of evil
            things.

15.d        Discussion: Such implementation-defined components are known in
            the vernacular as "dope." Their main purpose is for storing
            offsets of components that depend on discriminants.

16  If a record_representation_clause is given for an untagged derived type,
the storage place attributes for all of the components of the derived type may
differ from those of the corresponding components of the parent type, even for
components whose storage place is not specified explicitly in the record_-
representation_clause.

16.a        Reason: This is clearly necessary, since the whole record may need
            to be laid out differently.


                            Implementation Advice

17  The recommended level of support for record_representation_clauses is:

17.1/2   * {AI95-00133-01} An implementation should support machine scalars
        that correspond to all of the integer, floating point, and address
        formats supported by the machine.

18    * An implementation should support storage places that can be extracted
        with a load, mask, shift sequence of machine code, and set with a
        load, shift, mask, store sequence, given the available machine
        instructions and run-time model.

19    * A storage place should be supported if its size is equal to the Size
        of the component subtype, and it starts and ends on a boundary that
        obeys the Alignment of the component subtype.

20/2   * {AI95-00133-01} For a component with a subtype whose Size is less
        than the word size, any storage place that does not cross an aligned
        word boundary should be supported.

20.a        Reason: The above recommendations are sufficient to define
            interfaces to most interesting hardware. This causes less
            implementation burden than the definition in ACID, which requires
            arbitrary bit alignments of arbitrarily large components. Since
            the ACID definition is neither enforced by the ACVC, nor supported
            by all implementations, it seems OK for us to weaken it.

21    * An implementation may reserve a storage place for the tag field of a
        tagged type, and disallow other components from overlapping that
        place.

21.a        Ramification: Similar permission for other dope is not granted.

22    * An implementation need not support a component_clause for a component
        of an extension part if the storage place is not after the storage
        places of all components of the parent type, whether or not those
        storage places had been specified.

22.a        Reason: These restrictions are probably necessary if block
            equality operations are to be feasible for class-wide types. For
            block comparison to work, the implementation typically has to fill
            in any gaps with zero (or one) bits. If a "gap" in the parent type
            is filled in with a component in a type extension, then this won't
            work when a class-wide object is passed by reference, as is
            required.

22.b/2      Implementation Advice: The recommended level of support for
            record_representation_clauses should be followed.

        NOTES

23      14  If no component_clause is given for a component, then the choice
        of the storage place for the component is left to the implementation.
        If component_clauses are given for all components, the
        record_representation_clause completely specifies the representation
        of the type and will be obeyed exactly by the implementation.

23.a        Ramification: The visibility rules prevent the name of a component
            of the type from appearing in a record_representation_clause at
            any place except for the component_local_name of a
            component_clause. However, since the
            record_representation_clause is part of the declarative region of
            the type declaration, the component names hide outer homographs
            throughout.

23.b/1      {8652/0009} {AI95-00137-01} A record_representation_clause cannot
            be given for a protected type, even though protected types, like
            record types, have components. The primary reason for this rule is
            that there is likely to be too much dope in a protected type -
            entry queues, bit maps for barrier values, etc. In order to
            control the representation of the user-defined components, simply
            declare a record type, give it a record_representation_clause, and
            give the protected type one component whose type is the record
            type. Alternatively, if the protected object is protecting
            something like a device register, it makes more sense to keep the
            thing being protected outside the protected object (possibly with
            a pointer to it in the protected object), in order to keep
            implementation-defined components out of the way.


                                  Examples

24  Example of specifying the layout of a record type:

25      Word : constant := 4;  --  storage element is byte, 4 bytes per word

26      type State         is (A,M,W,P);
        type Mode          is (Fix, Dec, Exp, Signif);

27      type Byte_Mask     is array (0..7)  of Boolean;
        type State_Mask    is array (State) of Boolean;
        type Mode_Mask     is array (Mode)  of Boolean;

28      type Program_Status_Word is
          record
              System_Mask        : Byte_Mask;
              Protection_Key     : Integer range 0 .. 3;
              Machine_State      : State_Mask;
              Interrupt_Cause    : Interruption_Code;
              Ilc                : Integer range 0 .. 3;
              Cc                 : Integer range 0 .. 3;
              Program_Mask       : Mode_Mask;
              Inst_Address       : Address;
        end record;

29      for Program_Status_Word use
          record
              System_Mask      at 0*Word range 0  .. 7;
              Protection_Key   at 0*Word range 10 .. 11; -- bits 8,9 unused
              Machine_State    at 0*Word range 12 .. 15;
              Interrupt_Cause  at 0*Word range 16 .. 31;
              Ilc              at 1*Word range 0  .. 1;  -- second word
              Cc               at 1*Word range 2  .. 3;
              Program_Mask     at 1*Word range 4  .. 7;
              Inst_Address     at 1*Word range 8  .. 31;
          end record;

30      for Program_Status_Word'Size use 8*System.Storage_Unit;
        for Program_Status_Word'Alignment use 8;

        NOTES

31      15  Note on the example: The record_representation_clause defines the
        record layout. The Size clause guarantees that (at least) eight
        storage elements are used for objects of the type. The Alignment
        clause guarantees that aliased, imported, or exported objects of the
        type will have addresses divisible by eight.


                         Wording Changes from Ada 83

31.a        The alignment_clause has been renamed to mod_clause and moved to
            Annex J, "Obsolescent Features".

31.b        We have clarified that implementation-defined component names have
            to be in the form of an attribute_reference of a component or of
            the first subtype itself; surely Ada 83 did not intend to allow
            arbitrary identifiers.

31.c        The RM83-13.4(7) wording incorrectly allows components in
            nonvariant records to overlap. We have corrected that oversight.


                        Incompatibilities With Ada 95

31.d/2      {AI95-00133-01} Amendment Correction: The meaning of a
            record_representation_clause for the nondefault bit order is now
            clearly defined. Thus, such clauses can be portably written. In
            order to do that though, the equivalence of bit 1 in word 1 to bit
            9 in word 0 (for a machine with Storage_Unit = 8) had to be
            dropped for the nondefault bit order. Any
            record_representation_clauses which depends on that equivalence
            will break (although such code would imply a noncontiguous
            representation for a component, and it seems unlikely that
            compilers were supporting that anyway).


                            Extensions to Ada 95

31.e/2      {AI95-00436-01} Amendment Correction: The undocumented (and likely
            unintentional) incompatibility with Ada 83 caused by not allowing
            record_representation_clauses on limited record types is removed.


13.5.2 Storage Place Attributes



                              Static Semantics

1   For a component C of a composite, non-array object R, the storage place
attributes are defined:

1.a         Ramification: The storage place attributes are not (individually)
            specifiable, but the user may control their values by giving a
            record_representation_clause.

2/2 R.C'Position
                {AI95-00133-01} If the nondefault bit ordering applies to the
                composite type, and if a component_clause specifies the
                placement of C, denotes the value given for the position of
                the component_clause; otherwise, denotes the same value as
                R.C'Address - R'Address. The value of this attribute is of the
                type universal_integer.

2.a/2       Ramification: {AI95-00133-01} Thus, for the default bit order,
            R.C'Position is the offset of C in storage elements from the
            beginning of the object, where the first storage element of an
            object is numbered zero. R'Address + R.C'Position = R.C'Address.
            For record extensions, the offset is not measured from the
            beginning of the extension part, but from the beginning of the
            whole object, as usual.

2.b         In "R.C'Address - R'Address", the "-" operator is the one in
            System.Storage_Elements that takes two Addresses and returns a
            Storage_Offset.

3/2 R.C'First_Bit
                {AI95-00133-01} If the nondefault bit ordering applies to the
                composite type, and if a component_clause specifies the
                placement of C, denotes the value given for the first_bit of
                the component_clause; otherwise, denotes the offset, from the
                start of the first of the storage elements occupied by C, of
                the first bit occupied by C. This offset is measured in bits.
                The first bit of a storage element is numbered zero. The value
                of this attribute is of the type universal_integer.

4/2 R.C'Last_Bit
                {AI95-00133-01} If the nondefault bit ordering applies to the
                composite type, and if a component_clause specifies the
                placement of C, denotes the value given for the last_bit of
                the component_clause; otherwise, denotes the offset, from the
                start of the first of the storage elements occupied by C, of
                the last bit occupied by C. This offset is measured in bits.
                The value of this attribute is of the type universal_integer.

4.a/2       Ramification: {AI95-00114-01} The ordering of bits in a storage
            element is defined in 13.5.3, "Bit Ordering".

4.b         R.C'Size = R.C'Last_Bit - R.C'First_Bit + 1. (Unless the
            implementation chooses an indirection representation.)

4.c         If a component_clause applies to a component, then that component
            will be at the same relative storage place in all objects of the
            type. Otherwise, there is no such requirement.


                            Implementation Advice

5   If a component is represented using some form of pointer (such as an
offset) to the actual data of the component, and this data is contiguous with
the rest of the object, then the storage place attributes should reflect the
place of the actual data, not the pointer. If a component is allocated
discontiguously from the rest of the object, then a warning should be
generated upon reference to one of its storage place attributes.

5.a         Reason: For discontiguous components, these attributes make no
            sense. For example, an implementation might allocate dynamic-sized
            components on the heap. For another example, an implementation
            might allocate the discriminants separately from the other
            components, so that multiple objects of the same subtype can share
            discriminants. Such representations cannot happen if there is a
            component_clause for that component.

5.b/2       Implementation Advice: If a component is represented using a
            pointer to the actual data of the component which is contiguous
            with the rest of the object, then the storage place attributes
            should reflect the place of the actual data. If a component is
            allocated discontiguously from the rest of the object, then a
            warning should be generated upon reference to one of its storage
            place attributes.


                        Incompatibilities With Ada 95

5.c/2       {AI95-00133-01} Amendment Correction: The meaning of the storage
            place attributes for the nondefault bit order is now clearly
            defined, and can be different than that given by strictly
            following the Ada 95 wording. Any code which depends on the
            original Ada 95 values for a type using the nondefault bit order
            where they are different will break.


13.5.3 Bit Ordering


1   [The Bit_Order attribute specifies the interpretation of the storage place
attributes.]

1.a         Reason: The intention is to provide uniformity in the
            interpretation of storage places across implementations on a
            particular machine by allowing the user to specify the Bit_Order.
            It is not intended to fully support data interoperability across
            different machines, although it can be used for that purpose in
            some situations.

1.b/2       {AI95-00114-01} We can't require all implementations on a given
            machine to use the same bit ordering by default; if the user
            cares, a Bit_Order attribute_definition_clause can be used to
            force all implementations to use the same bit ordering.


                              Static Semantics

2   A bit ordering is a method of interpreting the meaning of the storage
place attributes. High_Order_First [(known in the vernacular as "big endian"
)] means that the first bit of a storage element (bit 0) is the most
significant bit (interpreting the sequence of bits that represent a component
as an unsigned integer value). Low_Order_First [(known in the vernacular as
"little endian")] means the opposite: the first bit is the least significant.

3   For every specific record subtype S, the following attribute is defined:

4   S'Bit_Order Denotes the bit ordering for the type of S. The value of this
                attribute is of type System.Bit_Order. Bit_Order may be
                specified for specific record types via an
                attribute_definition_clause; the expression of such a clause
                shall be static.

4.a/3       Aspect Description for Bit_Order: Order of bit numbering in a
            record_representation_clause.

5   If Word_Size = Storage_Unit, the default bit ordering is implementation
defined. If Word_Size > Storage_Unit, the default bit ordering is the same as
the ordering of storage elements in a word, when interpreted as an integer.

5.a         Implementation defined: If Word_Size = Storage_Unit, the default
            bit ordering.

5.b         Ramification: Consider machines whose Word_Size = 32, and whose
            Storage_Unit = 8. Assume the default bit ordering applies. On a
            machine with big-endian addresses, the most significant storage
            element of an integer is at the address of the integer. Therefore,
            bit zero of a storage element is the most significant bit. On a
            machine with little-endian addresses, the least significant
            storage element of an integer is at the address of the integer.
            Therefore, bit zero of a storage element is the least significant
            bit.

6   The storage place attributes of a component of a type are interpreted
according to the bit ordering of the type.

6.a         Ramification: This implies that the interpretation of the
            position, first_bit, and last_bit of a component_clause of a
            record_representation_clause obey the bit ordering given in a
            representation item.


                            Implementation Advice

7   The recommended level of support for the nondefault bit ordering is:

8/2   * {AI95-00133-01} The implementation should support the nondefault bit
        ordering in addition to the default bit ordering.

8.a/2       Ramification: {AI95-00133-01} The implementation should support
            both bit orderings. Implementations are required to support
            storage positions that cross storage element boundaries when
            Word_Size > Storage_Unit but the definition of the storage place
            attributes for the nondefault bit order ensures that such storage
            positions will not be split into two or three pieces. Thus, there
            is no significant implementation burden to supporting the
            nondefault bit order, given that the set of machine scalars is
            implementation-defined.

8.b/2       Implementation Advice: The recommended level of support for the
            nondefault bit ordering should be followed.

        NOTES

9/2     16  {AI95-00133-01} Bit_Order clauses make it possible to write
        record_representation_clauses that can be ported between machines
        having different bit ordering. They do not guarantee transparent
        exchange of data between such machines.


                            Extensions to Ada 83

9.a         The Bit_Order attribute is new to Ada 95.


                         Wording Changes from Ada 95

9.b/2       {AI95-00133-01} We now suggest that all implementations support
            the nondefault bit order.


13.6 Change of Representation


1/3 {AI05-0229-1} [ A type_conversion (see 4.6) can be used to convert between
two different representations of the same array or record. To convert an array
from one representation to another, two array types need to be declared with
matching component subtypes, and convertible index types. If one type has Pack
specified and the other does not, then explicit conversion can be used to pack
or unpack an array.

2   To convert a record from one representation to another, two record types
with a common ancestor type need to be declared, with no inherited
subprograms. Distinct representations can then be specified for the record
types, and explicit conversion between the types can be used to effect a
change in representation.]

2.a         Ramification: This technique does not work if the first type is an
            untagged type with user-defined primitive subprograms. It does not
            work at all for tagged types.


                                  Examples

3   Example of change of representation:

4       -- Packed_Descriptor and Descriptor are two different types
        -- with identical characteristics, apart from their
        -- representation

5       type Descriptor is
            record
              -- components of a descriptor
            end record;

6       type Packed_Descriptor is new Descriptor;

7       for Packed_Descriptor use
            record
              -- component clauses for some or for all components
            end record;

8       -- Change of representation can now be accomplished by explicit type conversions:

9       D : Descriptor;
        P : Packed_Descriptor;

10      P := Packed_Descriptor(D);  -- pack D
        D := Descriptor(P);         -- unpack P


13.7 The Package System


1   [For each implementation there is a library package called System which
includes the definitions of certain configuration-dependent characteristics.]


                              Static Semantics

2   The following language-defined library package exists:

2.a/2       Implementation defined: The contents of the visible part of
            package System.

3/2     {AI95-00362-01} package System is
           pragma Pure(System);

4          type Name is implementation-defined-enumeration-type;
           System_Name : constant Name := implementation-defined;

5          -- System-Dependent Named Numbers:

6          Min_Int               : constant := root_integer'First;
           Max_Int               : constant := root_integer'Last;

7          Max_Binary_Modulus    : constant := implementation-defined;
           Max_Nonbinary_Modulus : constant := implementation-defined;

8          Max_Base_Digits       : constant := root_real'Digits;
           Max_Digits            : constant := implementation-defined;

9          Max_Mantissa          : constant := implementation-defined;
           Fine_Delta            : constant := implementation-defined;

10         Tick                  : constant := implementation-defined;

11         -- Storage-related Declarations:

12         type Address is implementation-defined;
           Null_Address : constant Address;

13         Storage_Unit : constant := implementation-defined;
           Word_Size    : constant := implementation-defined * Storage_Unit;
           Memory_Size  : constant := implementation-defined;

14/3    {AI05-0229-1}    -- Address Comparison:
           function "<" (Left, Right : Address) return Boolean
              with Convention => Intrinsic;
           function "<="(Left, Right : Address) return Boolean
              with Convention => Intrinsic;
           function ">" (Left, Right : Address) return Boolean
              with Convention => Intrinsic;
           function ">="(Left, Right : Address) return Boolean
              with Convention => Intrinsic;
           function "=" (Left, Right : Address) return Boolean
              with Convention => Intrinsic;
        -- function "/=" (Left, Right : Address) return Boolean;
           -- "/=" is implicitly defined

15/2    {AI95-00221-01}    -- Other System-Dependent Declarations:
           type Bit_Order is (High_Order_First, Low_Order_First);
           Default_Bit_Order : constant Bit_Order := implementation-defined;

16         -- Priority-related declarations (see D.1):
           subtype Any_Priority is Integer range implementation-defined;
           subtype Priority is Any_Priority range Any_Priority'First ..
                     implementation-defined;
           subtype Interrupt_Priority is Any_Priority range Priority'Last+1 ..
                     Any_Priority'Last;

17         Default_Priority : constant Priority :=
                     (Priority'First + Priority'Last)/2;

18      private
           ... -- not specified by the language
        end System;

19  Name is an enumeration subtype. Values of type Name are the names of
alternative machine configurations handled by the implementation. System_Name
represents the current machine configuration.

20  The named numbers Fine_Delta and Tick are of the type universal_real; the
others are of the type universal_integer.

21  The meanings of the named numbers are:

22  [ Min_Int   The smallest (most negative) value allowed for the expressions
                of a signed_integer_type_definition.

23  Max_Int     The largest (most positive) value allowed for the expressions
                of a signed_integer_type_definition.

24  Max_Binary_Modulus
                A power of two such that it, and all lesser positive powers of
                two, are allowed as the modulus of a modular_type_definition.

25  Max_Nonbinary_Modulus
                A value such that it, and all lesser positive integers, are
                allowed as the modulus of a modular_type_definition.

25.a        Ramification: There is no requirement that Max_Nonbinary_Modulus
            be less than or equal to Max_Binary_Modulus, although that's what
            makes most sense. On a typical 32-bit machine, for example,
            Max_Binary_Modulus will be 2**32 and Max_Nonbinary_Modulus will be
            2**31, because supporting nonbinary moduli in above 2**31 causes
            implementation difficulties.

26  Max_Base_Digits
                The largest value allowed for the requested decimal precision
                in a floating_point_definition.

27  Max_Digits  The largest value allowed for the requested decimal precision
                in a floating_point_definition that has no
                real_range_specification. Max_Digits is less than or equal to
                Max_Base_Digits.

28  Max_Mantissa
                The largest possible number of binary digits in the mantissa
                of machine numbers of a user-defined ordinary fixed point
                type. (The mantissa is defined in Annex G.)

29  Fine_Delta  The smallest delta allowed in an
                ordinary_fixed_point_definition that has the real_range_-
                specification range -1.0 .. 1.0. ]

30  Tick        A period in seconds approximating the real time interval
                during which the value of Calendar.Clock remains constant.

30.a        Ramification: There is no required relationship between
            System.Tick and Duration'Small, other than the one described here.

30.b        The inaccuracy of the delay_statement has no relation to Tick. In
            particular, it is possible that the clock used for the
            delay_statement is less accurate than Calendar.Clock.

30.c        We considered making Tick a run-time-determined quantity, to allow
            for easier configurability. However, this would not be upward
            compatible, and the desired configurability can be achieved using
            functionality defined in Annex D, "Real-Time Systems".

31  Storage_Unit
                The number of bits per storage element.

32  Word_Size   The number of bits per word.

33  Memory_Size An implementation-defined value [that is intended to reflect
                the memory size of the configuration in storage elements.]

33.a        Discussion: It is unspecified whether this refers to the size of
            the address space, the amount of physical memory on the machine,
            or perhaps some other interpretation of "memory size." In any
            case, the value has to be given by a static expression, even
            though the amount of memory on many modern machines is a dynamic
            quantity in several ways. Thus, Memory_Size is not very useful.

34/2 {AI95-00161-01} Address is a definite, nonlimited type with preelaborable
initialization (see 10.2.1). Address represents machine addresses capable of
addressing individual storage elements. Null_Address is an address that is
distinct from the address of any object or program unit.

34.a        Ramification: The implementation has to ensure that there is at
            least one address that nothing will be allocated to; Null_Address
            will be one such address.

34.b        Ramification: Address is the type of the result of the attribute
            Address.

34.c        Reason: Address is required to be nonlimited and definite because
            it is important to be able to assign addresses, and to declare
            uninitialized address variables.

34.d/2      Ramification: {AI95-00161-01} If System.Address is defined as a
            private type (as suggested below), it might be necessary to add a
            pragma Preelaborable_Initialization to the specification of System
            in order that Address have preelaborable initialization as
            required.

35/2 {AI95-00221-01} Default_Bit_Order shall be a static constant. See
13.5.3 for an explanation of Bit_Order and Default_Bit_Order.


                         Implementation Permissions

36/2 {AI95-00362-01} An implementation may add additional
implementation-defined declarations to package System and its children.
[However, it is usually better for the implementation to provide additional
functionality via implementation-defined children of System.]

36.a        Ramification: The declarations in package System and its children
            can be implicit. For example, since Address is not limited, the
            predefined "=" and "/=" operations are probably sufficient.
            However, the implementation is not required to use the predefined
            "=".


                            Implementation Advice

37  Address should be a private type.

37.a        Reason: This promotes uniformity by avoiding having
            implementation-defined predefined operations for the type. We
            don't require it, because implementations may want to stick with
            what they have.

37.a.1/2    Implementation Advice: Type System.Address should be a private
            type.

37.b        Implementation Note: It is not necessary for Address to be able to
            point at individual bits within a storage element. Nor is it
            necessary for it to be able to point at machine registers. It is
            intended as a memory address that matches the hardware's notion of
            an address.

37.c        The representation of the null value of a general access type
            should be the same as that of Null_Address; instantiations of
            Unchecked_Conversion should work accordingly. If the
            implementation supports interfaces to other languages, the
            representation of the null value of a general access type should
            be the same as in those other languages, if appropriate.

37.d        Note that the children of the Interfaces package will generally
            provide foreign-language-specific null values where appropriate.
            See UI-0065 regarding Null_Address.

        NOTES

38      17  There are also some language-defined child packages of System
        defined elsewhere.


                            Extensions to Ada 83

38.a.1/1    The declarations Max_Binary_Modulus, Max_Nonbinary_Modulus,
            Max_Base_Digits, Null_Address, Word_Size, Bit_Order,
            Default_Bit_Order, Any_Priority, Interrupt_Priority, and
            Default_Priority are added to System in Ada 95. The presence of
            ordering operators for type Address is also guaranteed (the
            existence of these depends on the definition of Address in an Ada
            83 implementation). We do not list these as incompatibilities, as
            the contents of System can vary between implementations anyway;
            thus a program that depends on the contents of System (by using
            use System; for example) is already at risk of being incompatible
            when moved between Ada implementations.


                         Wording Changes from Ada 83

38.a        Much of the content of System is standardized, to provide more
            uniformity across implementations. Implementations can still add
            their own declarations to System, but are encouraged to do so via
            children of System.

38.b        Some of the named numbers are defined more explicitly in terms of
            the standard numeric types.

38.c        The pragmas System_Name, Storage_Unit, and Memory_Size are no
            longer defined by the language. However, the corresponding
            declarations in package System still exist. Existing
            implementations may continue to support the three pragmas as
            implementation-defined pragmas, if they so desire.

38.d        Priority semantics, including subtype Priority, have been moved to
            the Real Time Annex.


                            Extensions to Ada 95

38.e/2      {AI95-00161-01} Amendment Correction: Type Address is defined to
            have preelaborable initialization, so that it can be used without
            restriction in preelaborated units. (If Address is defined to be a
            private type, as suggested by the Implementation Advice, in Ada 95
            it cannot be used in some contexts in a preelaborated units. This
            is an unnecessary portability issue.)

38.f/2      {AI95-00221-01} Amendment Correction: Default_Bit_Order is now a
            static constant.

38.g/2      {AI95-00362-01} Package System is now Pure, so it can be portably
            used in more places. (Ada 95 allowed it to be Pure, but did not
            require that.)


13.7.1 The Package System.Storage_Elements



                              Static Semantics

1   The following language-defined library package exists:

2/2     {AI95-00362-01} package System.Storage_Elements is
           pragma Pure(Storage_Elements);

3          type Storage_Offset is range implementation-defined;

4          subtype Storage_Count
         is Storage_Offset range 0..Storage_Offset'Last;

5          type Storage_Element is mod implementation-defined;
           for Storage_Element'Size use Storage_Unit;
           type Storage_Array is array
             (Storage_Offset range <>) of aliased Storage_Element;
           for Storage_Array'Component_Size use Storage_Unit;

6          -- Address Arithmetic:

7/3     {AI05-0229-1}
           function "+"(Left : Address; Right : Storage_Offset) return Address
              with Convention => Intrinsic;
           function "+"(Left : Storage_Offset; Right : Address) return Address
              with Convention => Intrinsic;
           function "-"(Left : Address; Right : Storage_Offset) return Address
              with Convention => Intrinsic;
           function "-"(Left, Right : Address) return Storage_Offset
              with Convention => Intrinsic;

8/3     {AI05-0229-1}    function "mod"(Left : Address; Right : Storage_Offset)
              return Storage_Offset
                 with Convention => Intrinsic;

9          -- Conversion to/from integers:

10/3    {AI05-0229-1}    type Integer_Address is implementation-defined;
           function To_Address(Value : Integer_Address) return Address
              with Convention => Intrinsic;
           function To_Integer(Value : Address) return Integer_Address
              with Convention => Intrinsic;

11/3    {AI05-0229-1} end System.Storage_Elements;

11.a/3      Reason: {AI05-0229-1} The Convention aspects imply that the
            attribute Access is not allowed for those operations.

11.b        The mod function is needed so that the definition of Alignment
            makes sense.

11.c/2      Implementation defined: The range of
            Storage_Elements.Storage_Offset, the modulus of
            Storage_Elements.Storage_Element, and the declaration of
            Storage_Elements.Integer_Address..

12  Storage_Element represents a storage element. Storage_Offset represents an
offset in storage elements. Storage_Count represents a number of storage
elements. Storage_Array represents a contiguous sequence of storage elements.

12.a        Reason: The index subtype of Storage_Array is Storage_Offset
            because we wish to allow maximum flexibility. Most Storage_Arrays
            will probably have a lower bound of 0 or 1, but other lower
            bounds, including negative ones, make sense in some situations.

12.b/2      This paragraph was deleted.{AI95-00114-01}

13  Integer_Address is a [(signed or modular)] integer subtype. To_Address and
To_Integer convert back and forth between this type and Address.


                         Implementation Requirements

14  Storage_Offset'Last shall be greater than or equal to Integer'Last or the
largest possible storage offset, whichever is smaller. Storage_Offset'First
shall be <= (-Storage_Offset'Last).

Paragraph 15 was deleted.


                            Implementation Advice

16  Operations in System and its children should reflect the target
environment semantics as closely as is reasonable. For example, on most
machines, it makes sense for address arithmetic to "wrap around." Operations
that do not make sense should raise Program_Error.

16.a.1/2    Implementation Advice: Operations in System and its children
            should reflect the target environment; operations that do not make
            sense should raise Program_Error.

16.a        Discussion: For example, on a segmented architecture, X < Y might
            raise Program_Error if X and Y do not point at the same segment
            (assuming segments are unordered). Similarly, on a segmented
            architecture, the conversions between Integer_Address and Address
            might not make sense for some values, and so might raise
            Program_Error.

16.b        Reason: We considered making Storage_Element a private type.
            However, it is better to declare it as a modular type in the
            visible part, since code that uses it is already low level, and
            might as well have access to the underlying representation. We
            also considered allowing Storage_Element to be any integer type,
            signed integer or modular, but it is better to have uniformity
            across implementations in this regard, and viewing storage
            elements as unsigned seemed to make the most sense.

16.c        Implementation Note: To_Address is intended for use in Address
            clauses. Implementations should overload To_Address if
            appropriate. For example, on a segmented architecture, it might
            make sense to have a record type representing a segment/offset
            pair, and have a To_Address conversion that converts from that
            record type to type Address.


                            Extensions to Ada 95

16.d/2      {AI95-00362-01} Package System.Storage_Elements is now Pure, so it
            can be portably used in more places. (Ada 95 allowed it to be
            Pure, but did not require that.)


13.7.2 The Package System.Address_To_Access_Conversions



                              Static Semantics

1   The following language-defined generic library package exists:

2       generic
            type Object(<>) is limited private;
        package System.Address_To_Access_Conversions is
           pragma Preelaborate(Address_To_Access_Conversions);

3/3     {AI05-0229-1}    type Object_Pointer is access all Object;
           function To_Pointer(Value : Address) return Object_Pointer
              with Convention => Intrinsic;
           function To_Address(Value : Object_Pointer) return Address
              with Convention => Intrinsic;

4/3     {AI05-0229-1} end System.Address_To_Access_Conversions;

5/2 {AI95-00230-01} The To_Pointer and To_Address subprograms convert back and
forth between values of types Object_Pointer and Address.
To_Pointer(X'Address) is equal to X'Unchecked_Access for any X that allows
Unchecked_Access. To_Pointer(Null_Address) returns null. For other addresses,
the behavior is unspecified. To_Address(null) returns Null_Address.
To_Address(Y), where Y /= null, returns Y.all'Address.

5.a/3       Discussion: {AI95-00114-01} {AI05-0005-1} The programmer should
            ensure that the address passed to To_Pointer is either
            Null_Address, or the address of an object of type Object. (If
            Object is not a by-reference type, the object ought to be aliased;
            recall that the Address attribute is not required to provide a
            useful result for other objects.) Otherwise, the behavior of the
            program is unspecified; it might raise an exception or crash, for
            example.

5.b         Reason: Unspecified is almost the same thing as erroneous; they
            both allow arbitrarily bad behavior. We don't say erroneous here,
            because the implementation might allow the address passed to
            To_Pointer to point at some memory that just happens to "look
            like" an object of type Object. That's not necessarily an error; it's
            just not portable. However, if the actual type passed to Object is
            (for example) an array type, the programmer would need to be aware
            of any dope that the implementation expects to exist, when passing
            an address that did not come from the Address attribute of an
            object of type Object.

5.c         One might wonder why To_Pointer and To_Address are any better than
            unchecked conversions. The answer is that Address does not
            necessarily have the same representation as an access type. For
            example, an access value might point at the bounds of an array
            when an address would point at the first element. Or an access
            value might be an offset in words from someplace, whereas an
            address might be an offset in bytes from the beginning of memory.


                         Implementation Permissions

6   An implementation may place restrictions on instantiations of
Address_To_Access_Conversions.

6.a         Ramification: For example, if the hardware requires aligned loads
            and stores, then dereferencing an access value that is not
            properly aligned might raise an exception.

6.b         For another example, if the implementation has chosen to use
            negative component offsets (from an access value), it might not be
            possible to preserve the semantics, since negative offsets from
            the Address are not allowed. (The Address attribute always points
            at "the first of the storage elements....") Note that while the
            implementation knows how to convert an access value into an
            address, it might not be able to do the reverse. To avoid generic
            contract model violations, the restriction might have to be
            detected at run time in some cases.


13.8 Machine Code Insertions


1   [ A machine code insertion can be achieved by a call to a subprogram whose
sequence_of_statements contains code_statements.]


                                   Syntax

2       code_statement ::= qualified_expression;

3       A code_statement is only allowed in the handled_sequence_of_statements
        of a subprogram_body. If a subprogram_body contains any
        code_statements, then within this subprogram_body the only allowed
        form of statement is a code_statement (labeled or not), the only
        allowed declarative_items are use_clauses, and no exception_handler is
        allowed (comments and pragmas are allowed as usual).


                            Name Resolution Rules

4   The qualified_expression is expected to be of any type.


                               Legality Rules

5   The qualified_expression shall be of a type declared in package
System.Machine_Code.

5.a         Ramification: This includes types declared in children of
            System.Machine_Code.

6   A code_statement shall appear only within the scope of a with_clause that
mentions package System.Machine_Code.

6.a         Ramification: Note that this is not a note; without this rule, it
            would be possible to write machine code in compilation units which
            depend on System.Machine_Code only indirectly.


                              Static Semantics

7   The contents of the library package System.Machine_Code (if provided) are
implementation defined. The meaning of code_statements is implementation
defined. [Typically, each qualified_expression represents a machine
instruction or assembly directive.]

7.a         Discussion: For example, an instruction might be a record with an
            Op_Code component and other components for the operands.

7.b         Implementation defined: The contents of the visible part of
            package System.Machine_Code, and the meaning of code_statements.


                         Implementation Permissions

8   An implementation may place restrictions on code_statements. An
implementation is not required to provide package System.Machine_Code.

        NOTES

9       18  An implementation may provide implementation-defined pragmas
        specifying register conventions and calling conventions.

10/2    19  {AI95-00318-02} Machine code functions are exempt from the rule
        that a return statement is required. In fact, return statements are
        forbidden, since only code_statements are allowed.

10.a        Discussion: The idea is that the author of a machine code
            subprogram knows the calling conventions, and refers to parameters
            and results accordingly. The implementation should document where
            to put the result of a machine code function, for example, "
            Scalar results are returned in register 0."

11      20  Intrinsic subprograms (see 6.3.1, "Conformance Rules") can also be
        used to achieve machine code insertions. Interface to assembly
        language can be achieved using the features in Annex B, "
        Interface to Other Languages".


                                  Examples

12  Example of a code statement:

13/3    {AI05-0229-1} M : Mask;
        procedure Set_Mask
          with Inline;

14      procedure Set_Mask is
          use System.Machine_Code; -- assume "with System.Machine_Code;"
         appears somewhere above
        begin
          SI_Format'(Code => SSM, B => M'Base_Reg, D => M'Disp);
          --  Base_Reg and Disp are implementation-defined attributes
        end Set_Mask;


                            Extensions to Ada 83

14.a        Machine code functions are allowed in Ada 95; in Ada 83, only
            procedures were allowed.


                         Wording Changes from Ada 83

14.b        The syntax for code_statement is changed to say "
            qualified_expression" instead of "subtype_mark'record_aggregate
            ". Requiring the type of each instruction to be a record type is
            overspecification.


13.9 Unchecked Type Conversions


1   [ An unchecked type conversion can be achieved by a call to an instance of
the generic function Unchecked_Conversion.]


                              Static Semantics

2   The following language-defined generic library function exists:

3/3     {AI05-0229-1} generic
           type Source(<>) is limited private;
           type Target(<>) is limited private;
        function Ada.Unchecked_Conversion(S : Source) return Target
           with Convention => Intrinsic;
        pragma Pure(Ada.Unchecked_Conversion);

3.a/3       Reason: {AI05-0229-1} The aspect Convention implies that the
            attribute Access is not allowed for instances of
            Unchecked_Conversion.


                              Dynamic Semantics

4   The size of the formal parameter S in an instance of Unchecked_Conversion
is that of its subtype. [This is the actual subtype passed to Source, except
when the actual is an unconstrained composite subtype, in which case the
subtype is constrained by the bounds or discriminants of the value of the
actual expression passed to S.]

5   If all of the following are true, the effect of an unchecked conversion is
to return the value of an object of the target subtype whose representation is
the same as that of the source object S:

6     * S'Size = Target'Size.

6.a         Ramification: Note that there is no requirement that the Sizes be
            known at compile time.

7/3   * {AI05-0078-1} S'Alignment is a multiple of Target'Alignment or
        Target'Alignment is zero.

8     * The target subtype is not an unconstrained composite subtype.

9     * S and the target subtype both have a contiguous representation.

10    * The representation of S is a representation of an object of the target
        subtype.

11/2 {AI95-00426-01} Otherwise, if the result type is scalar, the result of
the function is implementation defined, and can have an invalid representation
(see 13.9.1). If the result type is nonscalar, the effect is implementation
defined; in particular, the result can be abnormal (see 13.9.1).

11.a.1/2    Implementation defined: The result of unchecked conversion for
            instances with scalar result types whose result is not defined by
            the language.

11.a/2      Implementation defined: The effect of unchecked conversion for
            instances with nonscalar result types whose effect is not defined
            by the language.

11.a.1/2    Reason: {AI95-00426-01} Note the difference between these
            sentences; the first only says that the bits returned are
            implementation defined, while the latter allows any effect. The
            difference is because scalar objects should never be abnormal
            unless their assignment was disrupted or if they are a
            subcomponent of an abnormal composite object. Neither exception
            applies to instances of Unchecked_Conversion.

11.a.2/2    Ramification: {AI95-00426-01} Whenever unchecked conversions are
            used, it is the programmer's responsibility to ensure that these
            conversions maintain the properties that are guaranteed by the
            language for objects of the target type. For nonscalar types, this
            requires the user to understand the underlying run-time model of
            the implementation. The execution of a program that violates these
            properties by means of unchecked conversions returning a nonscalar
            type is erroneous. Properties of scalar types can be checked by
            using the Valid attribute (see 13.9.2); programs can avoid
            violating properties of the type (and erroneous execution) by
            careful use of this attribute.

11.b        An instance of Unchecked_Conversion can be applied to an object of
            a private type, assuming the implementation allows it.


                         Implementation Permissions

12  An implementation may return the result of an unchecked conversion by
reference, if the Source type is not a by-copy type. [In this case, the result
of the unchecked conversion represents simply a different (read-only) view of
the operand of the conversion.]

12.a        Ramification: In other words, the result object of a call on an
            instance of Unchecked_Conversion can occupy the same storage as
            the formal parameter S.

13  An implementation may place restrictions on Unchecked_Conversion.

13.a        Ramification: For example, an instantiation of
            Unchecked_Conversion for types for which unchecked conversion
            doesn't make sense may be disallowed.


                            Implementation Advice

14/2 {AI95-00051-02} Since the Size of an array object generally does not
include its bounds, the bounds should not be part of the converted data.

14.a.1/2    Implementation Advice: Since the Size of an array object generally
            does not include its bounds, the bounds should not be part of the
            converted data in an instance of Unchecked_Conversion.

14.a        Ramification: On the other hand, we have no advice to offer about
            discriminants and tag fields.

15  The implementation should not generate unnecessary run-time checks to
ensure that the representation of S is a representation of the target type. It
should take advantage of the permission to return by reference when possible.
Restrictions on unchecked conversions should be avoided unless required by the
target environment.

15.a.1/2    Implementation Advice: There should not be unnecessary run-time
            checks on the result of an Unchecked_Conversion; the result should
            be returned by reference when possible. Restrictions on
            Unchecked_Conversions should be avoided.

15.a        Implementation Note: As an example of an unnecessary run-time
            check, consider a record type with gaps between components. The
            compiler might assume that such gaps are always zero bits. If a
            value is produced that does not obey that assumption, then the
            program might misbehave. The implementation should not generate
            extra code to check for zero bits (except, perhaps, in a special
            error-checking mode).

16  The recommended level of support for unchecked conversions is:

17/3   * {AI05-0299-1} Unchecked conversions should be supported and should be
        reversible in the cases where this subclause defines the result. To
        enable meaningful use of unchecked conversion, a contiguous
        representation should be used for elementary subtypes, for statically
        constrained array subtypes whose component subtype is one of the
        subtypes described in this paragraph, and for record subtypes without
        discriminants whose component subtypes are described in this
        paragraph.

17.a/2      Implementation Advice: The recommended level of support for
            Unchecked_Conversion should be followed.


                         Wording Changes from Ada 95

17.b/2      {AI95-00051-02} The implementation advice about the size of array
            objects was moved to 13.3 so that all of the advice about Size is
            in one place.

17.c/2      {AI95-00426-01} Clarified that the result of Unchecked_Conversion
            for scalar types can be invalid, but not abnormal.


                        Wording Changes from Ada 2005

17.d/3      {AI05-0078-1} Correction: Relaxed the alignment requirement
            slightly, giving a defined result in more cases.


13.9.1 Data Validity


1   Certain actions that can potentially lead to erroneous execution are not
directly erroneous, but instead can cause objects to become abnormal.
Subsequent uses of abnormal objects can be erroneous.

2   A scalar object can have an invalid representation, which means that the
object's representation does not represent any value of the object's subtype.
The primary cause of invalid representations is uninitialized variables.

3   Abnormal objects and invalid representations are explained in this
subclause.


                              Dynamic Semantics

4   When an object is first created, and any explicit or default
initializations have been performed, the object and all of its parts are in
the normal state. Subsequent operations generally leave them normal. However,
an object or part of an object can become abnormal in the following ways:

5     * An assignment to the object is disrupted due to an abort (see 9.8) or
        due to the failure of a language-defined check (see 11.6).

6/2   * {AI95-00426-01} The object is not scalar, and is passed to an in out
        or out parameter of an imported procedure, the Read procedure of an
        instance of Sequential_IO, Direct_IO, or Storage_IO, or the stream
        attribute T'Read, if after return from the procedure the
        representation of the parameter does not represent a value of the
        parameter's subtype.

6.1/2   * {AI95-00426-01} The object is the return object of a function call
        of a nonscalar type, and the function is an imported function, an
        instance of Unchecked_Conversion, or the stream attribute T'Input, if
        after return from the function the representation of the return object
        does not represent a value of the function's subtype.

6.a/2       Discussion: We explicitly list the routines involved in order to
            avoid future arguments. All possibilities are listed.

6.b/2       We did not include Stream_IO.Read in the list above. A
            Stream_Element should include all possible bit patterns, and thus
            it cannot be invalid. Therefore, the parameter will always
            represent a value of its subtype. By omitting this routine, we
            make it possible to write arbitrary I/O operations without any
            possibility of abnormal objects.

6.2/2 {AI95-00426-01} [For an imported object, it is the programmer's
responsibility to ensure that the object remains in a normal state.]

6.c/2       Proof: This follows (and echos) the standard rule of interfacing;
            the programmer must ensure that Ada semantics are followed (see
            B.1).

7   Whether or not an object actually becomes abnormal in these cases is not
specified. An abnormal object becomes normal again upon successful completion
of an assignment to the object as a whole.


                             Erroneous Execution

8   It is erroneous to evaluate a primary that is a name denoting an abnormal
object, or to evaluate a prefix that denotes an abnormal object.

8.a/2       This paragraph was deleted.{AI95-00114-01}

8.b         Ramification: The in out or out parameter case does not apply to
            scalars; bad scalars are merely invalid representations, rather
            than abnormal, in this case.

8.c/2       Reason: {AI95-00114-01} The reason we allow access objects, and
            objects containing subcomponents of an access type, to become
            abnormal is because the correctness of an access value cannot
            necessarily be determined merely by looking at the bits of the
            object. The reason we allow scalar objects to become abnormal is
            that we wish to allow the compiler to optimize assuming that the
            value of a scalar object belongs to the object's subtype, if the
            compiler can prove that the object is initialized with a value
            that belongs to the subtype. The reason we allow composite objects
            to become abnormal is that such object might be represented with
            implicit levels of indirection; if those are corrupted, then even
            assigning into a component of the object, or simply asking for its
            Address, might have an unpredictable effect. The same is true if
            the discriminants have been destroyed.


                          Bounded (Run-Time) Errors

9   If the representation of a scalar object does not represent a value of the
object's subtype (perhaps because the object was not initialized), the object
is said to have an invalid representation. It is a bounded error to evaluate
the value of such an object. If the error is detected, either Constraint_Error
or Program_Error is raised. Otherwise, execution continues using the invalid
representation. The rules of the language outside this subclause assume that
all objects have valid representations. The semantics of operations on invalid
representations are as follows:

9.a         Discussion: The AARM is more explicit about what happens when the
            value of the case expression is an invalid representation.

9.b/2       Ramification: {AI95-00426-01} This includes the result object of
            functions, including the result of Unchecked_Conversion, T'Input,
            and imported functions.

10    * If the representation of the object represents a value of the object's
        type, the value of the type is used.

11    * If the representation of the object does not represent a value of the
        object's type, the semantics of operations on such representations is
        implementation-defined, but does not by itself lead to erroneous or
        unpredictable execution, or to other objects becoming abnormal.

11.a/2      Implementation Note: {AI95-00426-01} This means that the
            implementation must take care not to use an invalid representation
            in a way that might cause erroneous execution. For instance, the
            exception mandated for case_statements must be raised. Array
            indexing must not cause memory outside of the array to be written
            (and usually, not read either). These cases and similar cases may
            require explicit checks by the implementation.


                             Erroneous Execution

12/3 {AI95-00167-01} {AI05-0279-1} A call to an imported function or an
instance of Unchecked_Conversion is erroneous if the result is scalar, the
result object has an invalid representation, and the result is used other than
as the expression of an assignment_statement or an object_declaration, as the
object_name of an object_renaming_declaration, or as the prefix of a Valid
attribute. If such a result object is used as the source of an assignment, and
the assigned value is an invalid representation for the target of the
assignment, then any use of the target object prior to a further assignment to
the target object, other than as the prefix of a Valid attribute reference, is
erroneous.

12.a/2      Ramification: {AI95-00167-01} In a typical implementation, every
            bit pattern that fits in an object of a signed integer subtype
            will represent a value of the type, if not of the subtype.
            However, for an enumeration or floating point type, as well as
            some modular types, there are typically bit patterns that do not
            represent any value of the type. In such cases, the implementation
            ought to define the semantics of operations on the invalid
            representations in the obvious manner (assuming the bounded error
            is not detected): a given representation should be equal to
            itself, a representation that is in between the internal codes of
            two enumeration literals should behave accordingly when passed to
            comparison operators and membership tests, etc. We considered
            requiring such sensible behavior, but it resulted in too much
            arcane verbiage, and since implementations have little incentive
            to behave irrationally, such verbiage is not important to have.

12.b/2      {AI95-00167-01} If a stand-alone scalar object is initialized to a
            an in-range value, then the implementation can take advantage of
            the fact that the use of any out-of-range value has to be
            erroneous. Such an out-of-range value can be produced only by
            things like unchecked conversion, imported functions, and abnormal
            values caused by disruption of an assignment due to abort or to
            failure of a language-defined check. This depends on out-of-range
            values being checked before assignment (that is, checks are not
            optimized away unless they are proven redundant).

12.c        Consider the following example:

12.d/2          {AI95-00167-01} type My_Int is range 0..99;
                function Safe_Convert is new Unchecked_Conversion(My_Int, Integer);
                function Unsafe_Convert is new Unchecked_Conversion(My_Int, Positive);
                X : Positive := Safe_Convert(0); -- Raises Constraint_Error.
                Y : Positive := Unsafe_Convert(0); -- Bounded Error, may be invalid.
                B : Boolean  := Y'Valid; -- OK, B = False.
                Z : Positive := Y+1; -- Erroneous to use Y.

12.e/2      {AI95-00167-01} {AI95-00426-01} The call to Unsafe_Convert is a
            bounded error, which might raise Constraint_Error, Program_Error,
            or return an invalid value. Moreover, if an exception is not
            raised, most uses of that invalid value (including the use of Y)
            cause erroneous execution. The call to Safe_Convert is not
            erroneous. The result object is an object of subtype Integer
            containing the value 0. The assignment to X is required to do a
            constraint check; the fact that the conversion is unchecked does
            not obviate the need for subsequent checks required by the
            language rules.

12.e.1/2    {AI95-00167-01} {AI95-00426-01} The reason for delaying erroneous
            execution until the object is used is so that the invalid
            representation can be tested for validity using the Valid
            attribute (see 13.9.2) without causing execution to become
            erroneous. Note that this delay does not imply an exception will
            not be raised; an implementation could treat both conversions in
            the example in the same way and raise Constraint_Error.

12.e.2/3    {AI05-0279-1} The rules are defined in terms of the result object,
            and thus the name used to reference that object is irrelevant.
            That is why we don't need any special rules to describe what
            happens when the function result is renamed.

12.f        Implementation Note: If an implementation wants to have a "
            friendly" mode, it might always assign an uninitialized scalar a
            default initial value that is outside the object's subtype (if
            there is one), and check for this value on some or all reads of
            the object, so as to help detect references to uninitialized
            scalars. Alternatively, an implementation might want to provide an
            "unsafe" mode where it presumed even uninitialized scalars were
            always within their subtype.

12.g        Ramification: The above rules imply that it is a bounded error to
            apply a predefined operator to an object with a scalar
            subcomponent having an invalid representation, since this implies
            reading the value of each subcomponent. Either Program_Error or
            Constraint_Error is raised, or some result is produced, which if
            composite, might have a corresponding scalar subcomponent still
            with an invalid representation.

12.h        Note that it is not an error to assign, convert, or pass as a
            parameter a composite object with an uninitialized scalar
            subcomponent. In the other hand, it is a (bounded) error to apply
            a predefined operator such as =, <, and xor to a composite operand
            with an invalid scalar subcomponent.

13/3 {AI05-0054-2} The dereference of an access value is erroneous if it does
not designate an object of an appropriate type or a subprogram with an
appropriate profile, if it designates a nonexistent object, or if it is an
access-to-variable value that designates a constant object and it did not
originate from an attribute_reference applied to an aliased variable view of a
controlled or immutably limited object. [An access value whose dereference is
erroneous can exist, for example, because of Unchecked_Deallocation,
Unchecked_Access, or Unchecked_Conversion.]

13.a        Ramification: The above mentioned Unchecked_... features are not
            the only causes of such access values. For example, interfacing to
            other languages can also cause the problem.

13.b/3      {AI05-0054-2} We permit the use of access-to-variable values that
            designate constant objects so long as they originate from an
            aliased variable view of a controlled or immutably limited
            constant, such as during the initialization of a constant (both
            via the "current instance" and during a call to Initialize) or
            during an assignment (during a call to Adjust).

        NOTES

14      21  Objects can become abnormal due to other kinds of actions that
        directly update the object's representation; such actions are
        generally considered directly erroneous, however.


                         Wording Changes from Ada 83

14.a        In order to reduce the amount of erroneousness, we separate the
            concept of an undefined value into objects with invalid
            representation (scalars only) and abnormal objects.

14.b        Reading an object with an invalid representation is a bounded
            error rather than erroneous; reading an abnormal object is still
            erroneous. In fact, the only safe thing to do to an abnormal
            object is to assign to the object as a whole.


                         Wording Changes from Ada 95

14.c/2      {AI95-00167-01} The description of erroneous execution for
            Unchecked_Conversion and imported objects was tightened up so that
            using the Valid attribute to test such a value is not erroneous.

14.d/2      {AI95-00426-01} Clarified the definition of objects that can
            become abnormal; made sure that all of the possibilities are
            included.


                        Wording Changes from Ada 2005

14.e/3      {AI05-0054-2} Correction: Common programming techniques such as
            squirreling away an access to a controlled object during
            initialization and using a self-referencing discriminant (the
            so-called "Rosen trick") no longer are immediately erroneous if
            the object is declared constant, so these techniques can be used
            portably and safely. Practically, these techniques already worked
            as compilers did not take much advantage of this rule, so the
            impact of this change will be slight.

14.f/3      {AI05-0279-1} Correction: The description of erroneous execution
            for Unchecked_Conversion and imported objects was adjusted to
            clarify that renaming such an object is not, by itself, erroneous.


13.9.2 The Valid Attribute


1   The Valid attribute can be used to check the validity of data produced by
unchecked conversion, input, interface to foreign languages, and the like.


                              Static Semantics

2   For a prefix X that denotes a scalar object [(after any implicit
dereference)], the following attribute is defined:

3/4 X'Valid     {AI05-0153-3} {AI12-0071-1} Yields True if and only if the
                object denoted by X is normal, has a valid representation, and
                then, if the preceding conditions hold, the value of X also
                satisfies the predicates of the nominal subtype of X. The
                value of this attribute is of the predefined type Boolean.

3.a         Ramification: Having checked that X'Valid is True, it is safe to
            read the value of X without fear of erroneous execution caused by
            abnormality, or a bounded error caused by an invalid
            representation. Such a read will produce a value in the subtype of
            X.

        NOTES

4       22  Invalid data can be created in the following cases (not counting
        erroneous or unpredictable execution):

5         * an uninitialized scalar object,

6         * the result of an unchecked conversion,

7         * input,

8         * interface to another language (including machine code),

9         * aborting an assignment,

10        * disrupting an assignment due to the failure of a language-defined
            check (see 11.6), and

11        * use of an object whose Address has been specified.

12/4    23  {AI12-0071-1} Determining whether X is normal and has a valid
        representation as part of the evaluation of X'Valid is not considered
        to include an evaluation of X; hence, it is not an error to check the
        validity of an object that is invalid or abnormal. Determining whether
        X satisfies the predicates of its nominal subtype may include an
        evaluation of X, but only after it has been determined that X has a
        valid representation.

13/4    {AI12-0071-1} If X is volatile, the evaluation of X'Valid is
        considered a read of X.

13.a/4      Reason: Since an implementation is not allowed to add, remove, or
            reorder accesses to volatile objects, we have to define X'Valid as
            a read so that it is implementable for most subtypes as the value
            of the object is required.

14/2    24  {AI95-00426-01} The Valid attribute may be used to check the
        result of calling an instance of Unchecked_Conversion (or any other
        operation that can return invalid values). However, an exception
        handler should also be provided because implementations are permitted
        to raise Constraint_Error or Program_Error if they detect the use of
        an invalid representation (see 13.9.1).

14.a        Ramification: If X is of an enumeration type with a representation
            clause, then X'Valid checks that the value of X when viewed as an
            integer is one of the specified internal codes.

14.b        Reason: Valid is defined only for scalar objects because the
            implementation and description burden would be too high for other
            types. For example, given a typical run-time model, it is
            impossible to check the validity of an access value. The same
            applies to composite types implemented with internal pointers. One
            can check the validity of a composite object by checking the
            validity of each of its scalar subcomponents. The user should
            ensure that any composite types that need to be checked for
            validity are represented in a way that does not involve
            implementation-defined components, or gaps between components.
            Furthermore, such types should not contain access subcomponents.

14.c/2      This paragraph was deleted.{AI95-00114-01}


                            Extensions to Ada 83

14.d        X'Valid is new in Ada 95.


                         Wording Changes from Ada 95

14.e/2      {AI95-00426-01} Added a note explaining that handlers for
            Constraint_Error and Program_Error are needed in the general case
            of testing for validity. (An implementation could document cases
            where these are not necessary, but there is no language
            requirement.)


                        Wording Changes from Ada 2005

14.f/3      {AI05-0153-3} The validity check now also includes a check of the
            predicate aspects (see 3.2.4), if any, of the subtype of the
            object.


                        Wording Changes from Ada 2012

14.g/4      {AI12-0071-1} Corrigendum: Updated wording of the attributes
            X'Valid to use the new term "satisfies the predicates" (see
            3.2.4). Also updated the notes to make sense when evaluating
            predicates and testing validity of volatile objects.


13.10 Unchecked Access Value Creation


1   [The attribute Unchecked_Access is used to create access values in an
unsafe manner - the programmer is responsible for preventing "dangling
references."]


                              Static Semantics

2   The following attribute is defined for a prefix X that denotes an aliased
view of an object:

3   X'Unchecked_Access
                All rules and semantics that apply to X'Access (see 3.10.2)
                apply also to X'Unchecked_Access, except that, for the
                purposes of accessibility rules and checks, it is as if X were
                declared immediately within a library package.

3.a/3       Ramification: {AI05-0005-1} We say "rules and semantics" here so
            that library-level accessibility applies to the value created by
            X'Unchecked_Access as well as to the checks needed for the
            attribute itself. This means that any anonymous access values that
            inherit the accessibility of this attribute (such as access
            parameters) also act as if they have library-level accessibility.
            We don't want the "real" accessibility of the created value
            re-emerging at a later point - that would create
            hard-to-understand bugs.

        NOTES

4       25  This attribute is provided to support the situation where a local
        object is to be inserted into a global linked data structure, when the
        programmer knows that it will always be removed from the data
        structure prior to exiting the object's scope. The Access attribute
        would be illegal in this case (see 3.10.2, "
        Operations of Access Types").

4.a         Ramification: The expected type for X'Unchecked_Access is as for
            X'Access.

4.b         If an attribute_reference with Unchecked_Access is used as the
            actual parameter for an access parameter, an Accessibility_Check
            can never fail on that access parameter.

5       26  There is no Unchecked_Access attribute for subprograms.

5.a/2       Reason: {AI95-00254-01} Such an attribute would allow unsafe "
            downward closures", where an access value designating a more
            nested subprogram is passed to a less nested subprogram.
            (Anonymous access-to-subprogram parameters provide safe "downward
            closures".) This requires some means of reconstructing the global
            environment for the more nested subprogram, so that it can do
            up-level references to objects. The two methods of implementing
            up-level references are displays and static links. If unsafe
            downward closures were supported, each access-to-subprogram value
            would have to carry the static link or display with it. We don't
            want to require the space and time overhead of requiring the extra
            information for all access-to-subprogram types, especially as
            including it would make interfacing to other languages (like C)
            harder.

5.b         If desired, an instance of Unchecked_Conversion can be used to
            create an access value of a global access-to-subprogram type that
            designates a local subprogram. The semantics of using such a value
            are not specified by the language. In particular, it is not
            specified what happens if such subprograms make up-level
            references; even if the frame being referenced still exists, the
            up-level reference might go awry if the representation of a value
            of a global access-to-subprogram type doesn't include a static
            link.


13.11 Storage Management


1   [ Each access-to-object type has an associated storage pool. The storage
allocated by an allocator comes from the pool; instances of
Unchecked_Deallocation return storage to the pool. Several access types can
share the same pool.]

2/2 {AI95-00435-01} [A storage pool is a variable of a type in the class
rooted at Root_Storage_Pool, which is an abstract limited controlled type. By
default, the implementation chooses a standard storage pool for each
access-to-object type. The user may define new pool types, and may override
the choice of pool for an access-to-object type by specifying Storage_Pool for
the type.]

2.a         Ramification: By default, the implementation might choose to have
            a single global storage pool, which is used (by default) by all
            access types, which might mean that storage is reclaimed
            automatically only upon partition completion. Alternatively, it
            might choose to create a new pool at each accessibility level,
            which might mean that storage is reclaimed for an access type when
            leaving the appropriate scope. Other schemes are possible.

2.a.1/3     Glossary entry: Each access-to-object type has an associated
            storage pool object. The storage for an object created by an
            allocator comes from the storage pool of the type of the
            allocator. Some storage pools may be partitioned into subpools in
            order to support finer-grained storage management.


                               Legality Rules

3   If Storage_Pool is specified for a given access type, Storage_Size shall
not be specified for it.

3.a         Reason: The Storage_Pool determines the Storage_Size; hence it
            would not make sense to specify both. Note that this rule is
            simplified by the fact that the aspects in question cannot be
            specified for derived types, nor for nonfirst subtypes, so we
            don't have to worry about whether, say, Storage_Pool on a derived
            type overrides Storage_Size on the parent type. For the same
            reason, "specified" means the same thing as "directly specified"
            here.


                              Static Semantics

4   The following language-defined library package exists:

5       with Ada.Finalization;
        with System.Storage_Elements;
        package System.Storage_Pools is
            pragma Preelaborate(System.Storage_Pools);

6/2     {AI95-00161-01}     type Root_Storage_Pool is
                abstract new Ada.Finalization.Limited_Controlled with private;
            pragma Preelaborable_Initialization(Root_Storage_Pool);

7           procedure Allocate(
              Pool : in out Root_Storage_Pool;
              Storage_Address : out Address;
              Size_In_Storage_Elements : in Storage_Elements.Storage_Count;
              Alignment : in Storage_Elements.Storage_Count) is abstract;

8           procedure Deallocate(
              Pool : in out Root_Storage_Pool;
              Storage_Address : in Address;
              Size_In_Storage_Elements : in Storage_Elements.Storage_Count;
              Alignment : in Storage_Elements.Storage_Count) is abstract;

9           function Storage_Size(Pool : Root_Storage_Pool)
                return Storage_Elements.Storage_Count is abstract;

10      private
           ... -- not specified by the language
        end System.Storage_Pools;

10.a        Reason: The Alignment parameter is provided to Deallocate because
            some allocation strategies require it. If it is not needed, it can
            be ignored.

11  A storage pool type (or pool type) is a descendant of Root_Storage_Pool.
The elements of a storage pool are the objects allocated in the pool by
allocators.

11.a        Discussion: In most cases, an element corresponds to a single
            memory block allocated by Allocate. However, in some cases the
            implementation may choose to associate more than one memory block
            with a given pool element.

12/2 {8652/0009} {AI95-00137-01} {AI95-00435-01} For every access-to-object
subtype S, the following representation attributes are defined:

13  S'Storage_Pool
                Denotes the storage pool of the type of S. The type of this
                attribute is Root_Storage_Pool'Class.

14  S'Storage_Size
                Yields the result of calling Storage_Size(S'Storage_Pool)[,
                which is intended to be a measure of the number of storage
                elements reserved for the pool.] The type of this attribute is
                universal_integer.

14.a        Ramification: Storage_Size is also defined for task subtypes and
            objects - see 13.3.

14.b        Storage_Size is not a measure of how much un-allocated space is
            left in the pool. That is, it includes both allocated and
            unallocated space. Implementations and users may provide a
            Storage_Available function for their pools, if so desired.

15  Storage_Size or Storage_Pool may be specified for a nonderived
access-to-object type via an attribute_definition_clause; the name in a
Storage_Pool clause shall denote a variable.

15.a/3      Aspect Description for Storage_Pool: Pool of memory from which new
            will allocate for a given access type.

15.b/3      Aspect Description for Storage_Size (access): Sets memory size for
            allocations for an access type.

16/3 {AI05-0107-1} {AI05-0111-3} {AI05-0116-1} An allocator of a type T that
does not support subpools allocates storage from T's storage pool. If the
storage pool is a user-defined object, then the storage is allocated by
calling Allocate as described below. Allocators for types that support
subpools are described in 13.11.4.

16.a        Ramification: If the implementation chooses to represent the
            designated subtype in multiple pieces, one allocator evaluation
            might result in more than one call upon Allocate. In any case,
            allocators for the access type obtain all the required storage for
            an object of the designated type by calling the specified Allocate
            procedure.

16.b/3      This paragraph was deleted.{AI05-0107-1}

16.b.1/1    {8652/0111} {AI95-00103-01} If D (the designated type of T)
            includes subcomponents of other access types, they will be
            allocated from the storage pools for those types, even if those
            allocators are executed as part of the allocator of T (as part of
            the initialization of the object). For instance, an access-to-task
            type TT may allocate the data structures used to implement the
            task value from other storage pools. (In particular, the task
            stack does not necessarily need to be allocated from the storage
            pool for TT.)

17  If Storage_Pool is not specified for a type defined by an
access_to_object_definition, then the implementation chooses a standard
storage pool for it in an implementation-defined manner. In this case, the
exception Storage_Error is raised by an allocator if there is not enough
storage. It is implementation defined whether or not the implementation
provides user-accessible names for the standard pool type(s).

17.a/2      This paragraph was deleted.

17.a.1/2    Discussion: The manner of choosing a storage pool is covered by a
            Documentation Requirement below, so it is not summarized here.

17.b        Implementation defined: Whether or not the implementation provides
            user-accessible names for the standard pool type(s).

17.c/2      Ramification: {AI95-00230-01} An access-to-object type defined by
            a derived_type_definition inherits its pool from its parent type,
            so all access-to-object types in the same derivation class share
            the same pool. Hence the "defined by an
            access_to_object_definition" wording above.

17.d        There is no requirement that all storage pools be implemented
            using a contiguous block of memory (although each allocation
            returns a pointer to a contiguous block of memory).

18/4 {AI12-0043-1} If Storage_Size is specified for an access type T, an
implementation-defined pool P is used for the type. The Storage_Size of P is
at least that requested, and the storage for P is reclaimed when the master
containing the declaration of the access type is left. If the implementation
cannot satisfy the request, Storage_Error is raised at the freezing point of
type T. The storage pool P is used only for allocators returning type T or
other access types specified to use T'Storage_Pool. Storage_Error is raised by
an allocator returning such a type if the storage space of P is exhausted
(additional memory is not allocated).

18.1/4 {AI12-0043-1} If neither Storage_Pool nor Storage_Size are specified,
then the meaning of Storage_Size is implementation defined.

18.a/2      Implementation defined: The meaning of Storage_Size when neither
            the Storage_Size nor the Storage_Pool is specified for an access
            type.

18.b        Ramification: The Storage_Size function and attribute will return
            the actual size, rather than the requested size. Comments about
            rounding up, zero, and negative on task Storage_Size apply here,
            as well. See also AI83-00557, AI83-00558, and AI83-00608.

18.c        The expression in a Storage_Size clause need not be static.

18.d        The reclamation happens after the master is finalized.

18.e        Implementation Note: For a pool allocated on the stack, normal
            stack cut-back can accomplish the reclamation. For a library-level
            pool, normal partition termination actions can accomplish the
            reclamation.

19  If Storage_Pool is specified for an access type, then the specified pool
is used.

20  The effect of calling Allocate and Deallocate for a standard storage pool
directly (rather than implicitly via an allocator or an instance of
Unchecked_Deallocation) is unspecified.

20.a        Ramification: For example, an allocator might put the pool element
            on a finalization list. If the user directly Deallocates it,
            instead of calling an instance of Unchecked_Deallocation, then the
            implementation would probably try to finalize the object upon
            master completion, which would be bad news. Therefore, the
            implementation should define such situations as erroneous.


                             Erroneous Execution

21  If Storage_Pool is specified for an access type, then if Allocate can
satisfy the request, it should allocate a contiguous block of memory, and
return the address of the first storage element in Storage_Address. The block
should contain Size_In_Storage_Elements storage elements, and should be
aligned according to Alignment. The allocated storage should not be used for
any other purpose while the pool element remains in existence. If the request
cannot be satisfied, then Allocate should propagate an exception [(such as
Storage_Error)]. If Allocate behaves in any other manner, then the program
execution is erroneous.


                         Implementation Requirements

21.1/3 {AI05-0107-1} {AI05-0262-1} The Allocate procedure of a user-defined
storage pool object P may be called by the implementation only to allocate
storage for a type T whose pool is P, only at the following points:

21.2/3   * During the execution of an allocator of type T;

21.a/3      Ramification: This includes during the evaluation of the
            initializing expression such as an aggregate; this is important if
            the initializing expression is built in place. We need to allow
            allocation to be deferred until the size of the object is known.

21.3/3   * During the execution of a return statement for a function whose
        result is built-in-place in the result of an allocator of type T;

21.b/3      Reason: We need this bullet as well as the preceding one in order
            that exceptions that propagate from such a call to Allocate can be
            handled within the return statement. We don't want to require the
            generation of special handling code in this unusual case, as it
            would add overhead to most return statements of composite types.

21.4/3   * During the execution of an assignment operation with a target of an
        allocated object of type T with a part that has an unconstrained
        discriminated subtype with defaults.

21.c/3      Reason: We allow Allocate to be called during assignment of
            objects with mutable parts so that mutable objects can be
            implemented with reallocation on assignment. (Unfortunately, the
            term "mutable" is only defined in the AARM, so we have to use the
            long-winded wording shown here.)

21.d/3      Discussion: Of course, explicit calls to Allocate are also allowed
            and are not bound by any of the rules found here.

21.5/3 {AI05-0107-1} {AI05-0116-1} {AI05-0193-1} {AI05-0262-1} {AI05-0269-1}
For each of the calls of Allocate described above, P (equivalent to
T'Storage_Pool) is passed as the Pool parameter. The Size_In_Storage_Elements
parameter indicates the number of storage elements to be allocated, and is no
more than D'Max_Size_In_Storage_Elements, where D is the designated subtype of
T. The Alignment parameter is a nonzero integral multiple of D'Alignment if D
is a specific type, and otherwise is a nonzero integral multiple of the
alignment of the specific type identified by the tag of the object being
created; it is unspecified if there is no such value. The Alignment parameter
is no more than D'Max_Alignment_For_Allocation. The result returned in the
Storage_Address parameter is used as the address of the allocated storage,
which is a contiguous block of memory of Size_In_Storage_Elements storage
elements. [Any exception propagated by Allocate is propagated by the construct
that contained the call.]

21.e/3      Ramification: Note that the implementation does not turn other
            exceptions into Storage_Error.

21.f/3      "Nonzero integral multiple" of an alignment includes the alignment
            value itself, of course. The value is unspecified if the alignment
            of the specific type is zero.

21.6/3 {AI05-0107-1} The number of calls to Allocate needed to implement an
allocator for any particular type is unspecified. The number of calls to
Deallocate needed to implement an instance of Unchecked_Deallocation (see
13.11.2) for any particular object is the same as the number of Allocate calls
for that object.

21.g/3      Reason: This supports objects that are allocated in one or more
            parts. The second sentence prevents extra or missing calls to
            Deallocate.

21.h/3      To be honest: {AI05-0005-1} The number of calls to Deallocate from
            all sources for an object always will be the same as the number of
            calls to Allocate from all sources for that object. However, in
            unusual cases, not all of those Deallocate calls may be made by an
            instance of Unchecked_Deallocation. Specifically, in the unusual
            case of assigning to an object of a mutable variant record type
            such that the variant changes, some of the Deallocate calls may be
            made by the assignment (as may some of the Allocate calls).

21.i/3      Ramification: We do not define the relative order of multiple
            calls used to deallocate the same object - that is, if the
            allocator allocated two pieces x and y, then an instance of
            Unchecked_Deallocation might deallocate x and then y, or it might
            deallocate y and then x.

21.7/3 {AI05-0107-1} The Deallocate procedure of a user-defined storage pool
object P may be called by the implementation to deallocate storage for a type
T whose pool is P only at the places when an Allocate call is allowed for P,
during the execution of an instance of Unchecked_Deallocation for T, or as
part of the finalization of the collection of T. For such a call of
Deallocate, P (equivalent to T'Storage_Pool) is passed as the Pool parameter.
The value of the Storage_Address parameter for a call to Deallocate is the
value returned in the Storage_Address parameter of the corresponding
successful call to Allocate. The values of the Size_In_Storage_Elements and
Alignment parameters are the same values passed to the corresponding Allocate
call. Any exception propagated by Deallocate is propagated by the construct
that contained the call.

21.j/3      Reason: We allow Deallocate to be called anywhere that Allocate
            is, in order to allow the recovery of storage from failed
            allocations (that is, those that raise exceptions); from extended
            return statements that exit via a goto, exit, or locally handled
            exception; and from objects that are reallocated when they are
            assigned. In each of these cases, we would have a storage leak if
            the implementation did not recover the storage (there is no way
            for the programmer to do it). We do not require such recovery,
            however, as it could be a serious performance drag on these
            operations.


                         Documentation Requirements

22  An implementation shall document the set of values that a user-defined
Allocate procedure needs to accept for the Alignment parameter. An
implementation shall document how the standard storage pool is chosen, and how
storage is allocated by standard storage pools.

22.a/2      This paragraph was deleted.

22.b/2      Documentation Requirement: The set of values that a user-defined
            Allocate procedure needs to accept for the Alignment parameter.
            How the standard storage pool is chosen, and how storage is
            allocated by standard storage pools.


                            Implementation Advice

23  An implementation should document any cases in which it dynamically
allocates heap storage for a purpose other than the evaluation of an
allocator.

23.a.1/2    Implementation Advice: Any cases in which heap storage is
            dynamically allocated other than as part of the evaluation of an
            allocator should be documented.

23.a        Reason: This is "Implementation Advice" because the term "heap
            storage" is not formally definable; therefore, it is not testable
            whether the implementation obeys this advice.

24  A default (implementation-provided) storage pool for an access-to-constant
type should not have overhead to support deallocation of individual objects.

24.a.1/2    Implementation Advice: A default storage pool for an
            access-to-constant type should not have overhead to support
            deallocation of individual objects.

24.a        Ramification: Unchecked_Deallocation is not defined for such
            types. If the access-to-constant type is library-level, then no
            deallocation (other than at partition completion) will ever be
            necessary, so if the size needed by an allocator of the type is
            known at link-time, then the allocation should be performed
            statically. If, in addition, the initial value of the designated
            object is known at compile time, the object can be allocated to
            read-only memory.

24.b        Implementation Note: If the Storage_Size for an access type is
            specified, the storage pool should consist of a contiguous block
            of memory, possibly allocated on the stack. The pool should
            contain approximately this number of storage elements. These
            storage elements should be reserved at the place of the
            Storage_Size clause, so that allocators cannot raise Storage_Error
            due to running out of pool space until the appropriate number of
            storage elements has been used up. This approximate (possibly
            rounded-up) value should be used as a maximum; the implementation
            should not increase the size of the pool on the fly. If the
            Storage_Size for an access type is specified as zero, then the
            pool should not take up any storage space, and any allocator for
            the type should raise Storage_Error.

24.c        Ramification: Note that most of this is approximate, and so cannot
            be (portably) tested. That's why we make it an Implementation
            Note. There is no particular number of allocations that is
            guaranteed to succeed, and there is no particular number of
            allocations that is guaranteed to fail.

25/2 {AI95-00230-01} The storage pool used for an allocator of an anonymous
access type should be determined as follows:

25.1/2   * {AI95-00230-01} {AI95-00416-01} If the allocator is defining a
        coextension (see 3.10.2) of an object being created by an outer
        allocator, then the storage pool used for the outer allocator should
        also be used for the coextension;

25.2/2   * {AI95-00230-01} For other access discriminants and access
        parameters, the storage pool should be created at the point of the
        allocator, and be reclaimed when the allocated object becomes
        inaccessible;

25.3/3   * {AI05-0051-1} If the allocator defines the result of a function
        with an access result, the storage pool is determined as though the
        allocator were in place of the call of the function. If the call is
        the operand of a type conversion, the storage pool is that of the
        target access type of the conversion. If the call is itself defining
        the result of a function with an access result, this rule is applied
        recursively;

25.4/2   * {AI95-00230-01} Otherwise, a default storage pool should be created
        at the point where the anonymous access type is elaborated; such a
        storage pool need not support deallocation of individual objects.

25.a.1/2    Implementation Advice: Usually, a storage pool for an access
            discriminant or access parameter should be created at the point of
            an allocator, and be reclaimed when the designated object becomes
            inaccessible. For other anonymous access types, the pool should be
            created at the point where the type is elaborated and need not
            support deallocation of individual objects.

25.a/2      Implementation Note: {AI95-00230-01} For access parameters and
            access discriminants, the "storage pool" for an anonymous access
            type would not normally exist as a separate entity. Instead, the
            designated object of the allocator would be allocated, in the case
            of an access parameter, as a local aliased variable at the call
            site, and in the case of an access discriminant, contiguous with
            the object containing the discriminant. This is similar to the way
            storage for aggregates is typically managed.

25.b/2      {AI95-00230-01} For other sorts of anonymous access types, this
            implementation is not possible in general, as the accessibility of
            the anonymous access type is that of its declaration, while the
            allocator could be more nested. In this case, a "real" storage
            pool is required. Note, however, that this storage pool need not
            support (separate) deallocation, as it is not possible to
            instantiate Unchecked_Deallocation with an anonymous access type.
            (If deallocation is needed, the object should be allocated for a
            named access type and converted.) Thus, deallocation only need
            happen when the anonymous access type itself goes out of scope;
            this is similar to the case of an access-to-constant type.

        NOTES

26      27  A user-defined storage pool type can be obtained by extending the
        Root_Storage_Pool type, and overriding the primitive subprograms
        Allocate, Deallocate, and Storage_Size. A user-defined storage pool
        can then be obtained by declaring an object of the type extension. The
        user can override Initialize and Finalize if there is any need for
        nontrivial initialization and finalization for a user-defined pool
        type. For example, Finalize might reclaim blocks of storage that are
        allocated separately from the pool object itself.

27      28  The writer of the user-defined allocation and deallocation
        procedures, and users of allocators for the associated access type,
        are responsible for dealing with any interactions with tasking. In
        particular:

28        * If the allocators are used in different tasks, they require mutual
            exclusion.

29        * If they are used inside protected objects, they cannot block.

30        * If they are used by interrupt handlers (see C.3, "
            Interrupt Support"), the mutual exclusion mechanism has to work
            properly in that context.

31      29  The primitives Allocate, Deallocate, and Storage_Size are declared
        as abstract (see 3.9.3), and therefore they have to be overridden when
        a new (nonabstract) storage pool type is declared.

31.a        Ramification: Note that the Storage_Pool attribute denotes an
            object, rather than a value, which is somewhat unusual for
            attributes.

31.b        The calls to Allocate, Deallocate, and Storage_Size are
            dispatching calls - this follows from the fact that the actual
            parameter for Pool is T'Storage_Pool, which is of type
            Root_Storage_Pool'Class. In many cases (including all cases in
            which Storage_Pool is not specified), the compiler can determine
            the tag statically. However, it is possible to construct cases
            where it cannot.

31.c        All access types in the same derivation class share the same pool,
            whether implementation defined or user defined. This is necessary
            because we allow type conversions among them (even if they are
            pool-specific), and we want pool-specific access values to always
            designate an element of the right pool.

31.d        Implementation Note: If an access type has a standard storage
            pool, then the implementation doesn't actually have to follow the
            pool interface described here, since this would be semantically
            invisible. For example, the allocator could conceivably be
            implemented with inline code.


                                  Examples

32  To associate an access type with a storage pool object, the user first
declares a pool object of some type derived from Root_Storage_Pool. Then, the
user defines its Storage_Pool attribute, as follows:

33      Pool_Object : Some_Storage_Pool_Type;

34      type T is access Designated;
        for T'Storage_Pool use Pool_Object;

35  Another access type may be added to an existing storage pool, via:

36      for T2'Storage_Pool use T'Storage_Pool;

37  The semantics of this is implementation defined for a standard storage
pool.

37.a        Reason: For example, the implementation is allowed to choose a
            storage pool for T that takes advantage of the fact that T is of a
            certain size. If T2 is not of that size, then the above will
            probably not work.

38/3 {AI05-0111-3} As usual, a derivative of Root_Storage_Pool may define
additional operations. For example, consider the Mark_Release_Pool_Type
defined in 13.11.6, that has two additional operations, Mark and Release, the
following is a possible use:

39/3    {8652/0041} {AI95-00066-01} {AI05-0111-3} type Mark_Release_Pool_Type
           (Pool_Size : Storage_Elements.Storage_Count)
                is new Subpools.Root_Storage_Pool_With_Subpools with private;
                   -- As defined in package MR_Pool, see 13.11.6

40      ...

41/3    {AI05-0111-3} Our_Pool : Mark_Release_Pool_Type (Pool_Size => 2000);
        My_Mark : MR_Pool.Subpool_Handle; -- See 13.11.6

42/3    {AI05-0111-3} type Acc is access ...;
        for Acc'Storage_Pool use Our_Pool;
        ...

43/3    {AI05-0111-3} My_Mark := Mark(Our_Pool);
        ... -- Allocate objects using "new (My_Mark) Designated(...)".
        Release(My_Mark); -- Finalize objects and reclaim storage.


                            Extensions to Ada 83

43.a        User-defined storage pools are new to Ada 95.


                         Wording Changes from Ada 83

43.b/3      {AI05-0005-1} {AI05-0190-1} Ada 83 originally introduced the
            concept called a "collection," which is similar to what we call a
            storage pool. All access types in the same derivation class share
            the same collection. Ada 95 introduces the storage pool, which is
            similar in that all access types in the same derivation class
            share the same storage pool, but other (unrelated) access types
            can also share the same storage pool, either by default, or as
            specified by the user. A collection is an amorphous grouping of
            objects (mainly used to describe finalization of access types); a
            storage pool is a more concrete concept - hence the different name.

43.c        RM83 states the erroneousness of reading or updating deallocated
            objects incorrectly by missing various cases.


                        Incompatibilities With Ada 95

43.d/2      {AI95-00435-01} Amendment Correction: Storage pools (and
            Storage_Size) are not defined for access-to-subprogram types. The
            original Ada 95 wording defined the attributes, but said nothing
            about their values. If a program uses attributes Storage_Pool or
            Storage_Size on an access-to-subprogram type, it will need to be
            corrected for Ada 2005. That's a good thing, as such a use is a
            bug - the concepts never were defined for such types.


                            Extensions to Ada 95

43.e/2      {AI95-00161-01} Amendment Correction: Added pragma
            Preelaborable_Initialization to type Root_Storage_Pool, so that
            extensions of it can be used to declare default-initialized
            objects in preelaborated units.


                         Wording Changes from Ada 95

43.f/2      {8652/0009} {AI95-00137-01} Corrigendum: Added wording to specify
            that these are representation attributes.

43.g/2      {AI95-00230-01} {AI95-00416-01} Added wording to clarify that an
            allocator for a coextension nested inside an outer allocator
            shares the pool with the outer allocator.


                        Wording Changes from Ada 2005

43.h/3      {AI05-0051-1} Correction: Added the missing definition of the
            storage pool of an allocator for an anonymous access result type.

43.i/3      {AI05-0107-1} Correction: Clarified when an implementation is
            allowed to call Allocate and Deallocate, and the requirements on
            such calls.

43.j/3      {AI05-0111-3} Added wording to support subpools and refer to the
            subpool example, see 13.11.4.

43.k/3      {AI05-0116-1} Correction: Added wording to specify that the
            alignment for an allocator with a class-wide designated type comes
            from the specific type that is allocated.

43.l/3      {AI05-0193-1} Added wording to allow larger alignments for calls
            to Allocate made by allocators, up to
            Max_Alignment_For_Allocation. This eases implementation in some
            cases.


                        Wording Changes from Ada 2012

43.m/4      {AI12-0043-1} Corrigendum: Tightened up the description of the
            implementation-defined pool used when Storage_Size is specified.
            This is not intended to change any implementation.


13.11.1 Storage Allocation Attributes


1/3 {AI05-0193-1} [The Max_Size_In_Storage_Elements and
Max_Alignment_For_Allocation attributes may be useful in writing user-defined
pool types.]


                              Static Semantics

2/3 {AI05-0193-1} For every subtype S, the following attributes are defined:

3/3 S'Max_Size_In_Storage_Elements
                {AI95-00256-01} {AI95-00416-01} {AI05-0193-1} Denotes the
                maximum value for Size_In_Storage_Elements that could be
                requested by the implementation via Allocate for an access
                type whose designated subtype is S. The value of this
                attribute is of type universal_integer.

3.a         Ramification: If S is an unconstrained array subtype, or an
            unconstrained subtype with discriminants,
            S'Max_Size_In_Storage_Elements might be very large.

4/3 S'Max_Alignment_For_Allocation
                {AI05-0193-1} Denotes the maximum value for Alignment that
                could be requested by the implementation via Allocate for an
                access type whose designated subtype is S. The value of this
                attribute is of type universal_integer.

5/3 {AI05-0193-1} For a type with access discriminants, if the implementation
allocates space for a coextension in the same pool as that of the object
having the access discriminant, then these attributes account for any calls on
Allocate that could be performed to provide space for such coextensions.

5.a/3       Reason: {AI05-0193-1} The values of these attributes should
            reflect only the calls that might be made to the pool specified
            for an access type with designated type S. Thus, if the
            coextensions would normally be allocated from a different pool
            than the one used for the main object (that is, the
            Implementation Advice of 13.11 for determining the pool of an
            anonymous access discriminant is not followed), then these
            attributes should not reflect any calls on Allocate used to
            allocate the coextensions.

5.b/3       Ramification: {AI05-0193-1} Coextensions of coextensions of this
            type (and so on) are included in the values of these attributes if
            they are allocated from the same pool.


                         Wording Changes from Ada 95

5.c/2       {AI95-00256-01} Corrected the wording so that a fortune-telling
            compiler that can see the future execution of the program is not
            required.


                           Extensions to Ada 2005

5.d/3       {AI05-0193-1} The Max_Alignment_For_Allocation attribute is new.


13.11.2 Unchecked Storage Deallocation


1   [ Unchecked storage deallocation of an object designated by a value of an
access type is achieved by a call to an instance of the generic procedure
Unchecked_Deallocation.]


                              Static Semantics

2   The following language-defined generic library procedure exists:

3/3     {AI05-0229-1} generic
           type Object(<>) is limited private;
           type Name   is access  Object;
        procedure Ada.Unchecked_Deallocation(X : in out Name)
           with Convention => Intrinsic;
        pragma Preelaborate(Ada.Unchecked_Deallocation);

3.a/3       Reason: {AI05-0229-1} The aspect Convention implies that the
            attribute Access is not allowed for instances of
            Unchecked_Deallocation.


                               Legality Rules

3.1/3 {AI05-0157-1} A call on an instance of Unchecked_Deallocation is illegal
if the actual access type of the instance is a type for which the Storage_Size
has been specified by a static expression with value zero or is defined by the
language to be zero. In addition to the places where Legality Rules normally
apply (see 12.3), this rule applies also in the private part of an instance of
a generic unit.

3.b/3       Discussion: This rule is the same as the rule for allocators. We
            could have left the last sentence out, as a call to
            Unchecked_Deallocation cannot occur in a specification as it is a
            procedure call, but we left it for consistency and to avoid future
            maintenance hazards.


                              Dynamic Semantics

4   Given an instance of Unchecked_Deallocation declared as follows:

5       procedure Free is
            new Ada.Unchecked_Deallocation(
                object_subtype_name, access_to_variable_subtype_name);

6   Procedure Free has the following effect:

7   1.  After executing Free(X), the value of X is null.

8   2.  Free(X), when X is already equal to null, has no effect.

9/3 3.  {AI95-00416-01} {AI05-0107-1} Free(X), when X is not equal to null
        first performs finalization of the object designated by X (and any
        coextensions of the object - see 3.10.2), as described in 7.6.1. It
        then deallocates the storage occupied by the object designated by X
        (and any coextensions). If the storage pool is a user-defined object,
        then the storage is deallocated by calling Deallocate as described in
        13.11. There is one exception: if the object being freed contains
        tasks, the object might not be deallocated.

9.a/3       Ramification: {AI05-0107-1} Free calls only the specified
            Deallocate procedure to do deallocation.

10/4 {AI95-00416-01} {AI12-0148-1} After the finalization step of Free(X), the
object designated by X, and any subcomponents (and coextensions) thereof, no
longer exist; their storage can be reused for other purposes.


                          Bounded (Run-Time) Errors

11  It is a bounded error to free a discriminated, unterminated task object.
The possible consequences are:

11.a        Reason: This is an error because the task might refer to its
            discriminants, and the discriminants might be deallocated by
            freeing the task object.

12    * No exception is raised.

13    * Program_Error or Tasking_Error is raised at the point of the
        deallocation.

14    * Program_Error or Tasking_Error is raised in the task the next time it
        references any of the discriminants.

14.a        Implementation Note: This last case presumes an implementation
            where the task references its discriminants indirectly, and the
            pointer is nulled out when the task object is deallocated.

15  In the first two cases, the storage for the discriminants (and for any
enclosing object if it is designated by an access discriminant of the task) is
not reclaimed prior to task termination.

15.a        Ramification: The storage might never be reclaimed.

15.1/4 {AI12-0148-1} An access value that designates a nonexistent object is
called a dangling reference.

15.b/4      Discussion: These can result from use of Unchecked_Deallocation,
            Unchecked_Deallocate_Subpool, and attribute Unchecked_Access. Bad
            results from Unchecked_Conversion and from stream-oriented
            attributes are abnormal by 13.9.1, which is stronger and thus
            takes precedence.

15.2/4 {AI12-0148-1} [If a dangling reference is dereferenced (implicitly or
explicitly), execution is erroneous (see below).] If there is no explicit or
implicit dereference, then it is a bounded error to evaluate an expression
whose result is a dangling reference. If the error is detected, either
Constraint_Error or Program_Error is raised. Otherwise, execution proceeds
normally, but with the possibility that the access value designates some other
existing object.

15.c/4      Reason: If a dangling reference is compared with another access
            value, a result of either True or False is allowed. We need to
            allow this so that simple implementations of access values (for
            instance, as a bare address) can work if the memory in question is
            reused. (The formal definition of access equality is that it
            returns True if both access values designate the same object; that
            can never be True if one of the values is a dangling reference,
            and the other is not, but both values could refer to the same
            memory.) Membership tests that do not involve an implicit
            dereference generally do not depend on the access value at all.

15.d/4      We allow Constraint_Error to be raised here so that dangling
            reference and null pointer checks can be combined into a single
            check. If different exceptions are required, then the checks have
            to be made separately - but there's little semantic difference
            (neither designate a usable object).

15.e/4      Ramification: If a dangling reference is assigned into an object,
            including being passed to a formal parameter, that object also
            contains a dangling reference afterwards.

15.f/4      Discussion: For equality and membership operations on composite
            types, this applies to any parts that are access types, as these
            operations are created based on the operations of the components
            (which triggers the bounded error). For other operations on
            composite types, the bounded error is not triggered. For instance,
            an assignment of a composite object with a subcomponent that is a
            dangling reference has to work normally; no exception can be
            raised, but the target object will have a subcomponent that is a
            dangling references, and a (direct) use of that subcomponent is
            again a bounded error. This is similar to the way that assignments
            of invalid subcomponents are handled (see 13.9.1).


                             Erroneous Execution

16/3 {AI05-0033-1} {AI05-0262-1} Evaluating a name that denotes a nonexistent
object, or a protected subprogram or subprogram renaming whose associated
object (if any) is nonexistent, is erroneous. The execution of a call to an
instance of Unchecked_Deallocation is erroneous if the object was created
other than by an allocator for an access type whose pool is Name'Storage_Pool.

16.a/3      Reason: {AI05-0033-1} {AI05-0262-1} The part about a protected
            subprogram is intended to cover the case of an
            access-to-protected-subprogram where the associated object has
            been deallocated. The part about a subprogram renaming is intended
            to cover the case of a renaming of a prefixed view where the
            prefix object has been deallocated, or the case of a renaming of
            an entry or protected subprogram where the associated task or
            protected object has been deallocated.

16.b/3      Ramification: {AI05-0157-1} This text does not cover the case of a
            name that contains a null access value, as null does not denote an
            object (rather than denoting a nonexistent object).


                            Implementation Advice

17  For a standard storage pool, Free should actually reclaim the storage.

17.a.1/2    Implementation Advice: For a standard storage pool, an instance of
            Unchecked_Deallocation should actually reclaim the storage.

17.a/2      Ramification: {AI95-00114-01} This is not a testable property,
            since we do not know how much storage is used by a given pool
            element, nor whether fragmentation can occur.

17.1/3 {AI05-0157-1} A call on an instance of Unchecked_Deallocation with a
nonnull access value should raise Program_Error if the actual access type of
the instance is a type for which the Storage_Size has been specified to be
zero or is defined by the language to be zero.

17.a.1/3    Implementation Advice: A call on an instance of
            Unchecked_Deallocation with a nonnull access value should raise
            Program_Error if the actual access type of the instance is a type
            for which the Storage_Size has been specified to be zero or is
            defined by the language to be zero.

17.b        Discussion: If the call is not illegal (as in a generic body), we
            recommend that it raise Program_Error. Since the execution of this
            call is erroneous (any allocator from the pool will have raised
            Storage_Error, so the nonnull access value must have been
            allocated from a different pool or be a stack-allocated object),
            we can't require any behavior - anything at all would be a
            legitimate implementation.

        NOTES

18      30  The rules here that refer to Free apply to any instance of
        Unchecked_Deallocation.

19      31  Unchecked_Deallocation cannot be instantiated for an
        access-to-constant type. This is implied by the rules of 12.5.4.


                         Wording Changes from Ada 95

19.a/2      {AI95-00416-01} The rules for coextensions are clarified (mainly
            by adding that term). In theory, this reflects no change from Ada
            95 (coextensions existed in Ada 95, they just didn't have a name).


                        Wording Changes from Ada 2005

19.b/3      {AI05-0033-1} Correction: Added a rule that using an
            access-to-protected-subprogram is erroneous if the associated
            object no longer exists. It is hard to imagine an alternative
            meaning here, and this has no effect on correct programs.

19.c/3      {AI05-0107-1} Correction: Moved the requirements on an
            implementation-generated call to Deallocate to 13.11, in order to
            put all of the rules associated with implementation-generated
            calls to Allocate and Deallocate together.

19.d/3      {AI05-0157-1} Correction: Added wording so that calling an
            instance of Unchecked_Deallocation is treated similarly to
            allocators for access types where allocators would be banned.


                        Inconsistencies With Ada 2012

19.e/4      {AI12-0148-1} Corrigendum: Defined a "dangling reference", and
            specified that a dangling reference might designate some other
            existing object. This allows simple implementations of access
            values and reuse of object memory after deallocation. In prior
            versions of Ada, "=" between a dangling reference and an access to
            an existing object has to return False, even if the existing
            object and the object designated by the dangling reference are
            allocated in the same memory. A program that depended upon that
            could break with this revised rule. However, as a practical
            matter, almost all Ada implementations use simple implementations
            of access types that do not meet that requirement. So such a
            program would not work (consistently) on most Ada implementations;
            thus the change shouldn't break any existing programs - it just
            aligns the Standard with actual practice.

19.f/4      {AI12-0148-1} A side effect of this change is to allow an Ada
            implementation to detect dangling references in more places. This
            does not require any Ada implementation to change, and if the
            implementation does change, it just means that errors will be
            detected earlier.


                        Wording Changes from Ada 2012

19.g/4      {AI12-0148-1} Corrigendum: Clarified that deallocated objects
            cease to exist after finalization but before Deallocate is called.
            This is necessary to prevent erroneous execution from being
            triggered by the rules in 13.11 in the time between the end of
            finalization and the end of the call to the instance of
            Unchecked_Deallocation.


13.11.3 Default Storage Pools


1/4 {AI05-0229-1} {AI12-0003-1} [Pragma and aspect Default_Storage_Pool
specify the storage pool that will be used in the absence of an explicit
specification of a storage pool or storage size for an access type.]


                                   Syntax

2/3     {AI05-0190-1} {AI05-0229-1} The form of a pragma Default_Storage_Pool
        is as follows:

3/3     {AI05-0190-1} {AI05-0229-1}   pragma Default_Storage_Pool
        (storage_pool_indicator);

3.1/4   {AI05-0190-1} {AI12-0003-1} storage_pool_indicator ::= 
        storage_pool_name | null | Standard

3.2/3   {AI05-0190-1} A pragma Default_Storage_Pool is allowed immediately
        within the visible part of a package_specification, immediately within
        a declarative_part, or as a configuration pragma.


                            Name Resolution Rules

3.3/3 {AI05-0190-1} The storage_pool_name is expected to be of type
Root_Storage_Pool'Class.


                               Legality Rules

4/3 {AI05-0190-1} {AI05-0229-1} The storage_pool_name shall denote a variable.

4.1/4 {AI12-0003-1} The Standard storage_pool_indicator is an identifier
specific to a pragma (see 2.8) and does not denote any declaration. If the
storage_pool_indicator is Standard, then there shall not be a declaration with
defining_identifier Standard that is immediately visible at the point of the
pragma, other than package Standard itself.

4.a.1/4     Reason: We considered having the Standard storage_pool_indicator
            resolve to package Standard rather than being an identifier
            specific to a pragma. That would eliminate the need for a special
            check. But it would be bizarre to have something that could
            resolve to either an object or a (single) package, and resolving
            to package Standard would imply that the standard pool is an
            object declared in that package. A storage pool object must be a
            variable (see 13.11), yet preelaborable packages depend on package
            Standard, which would require implementers to implement the
            standard storage pool with Preelaborable_Initialization, which is
            an unnecessary restriction.

4.a.2/4     No declaration of Standard can ever be use-visible, as the
            language-defined nonoverloadable definition of Standard will hide
            any use-visible declarations. Thus we need only concern ourselves
            with eliminating any possible confusion with regard to immediately
            visible declarations with the defining_identifier Standard.

4.2/4 {AI05-0190-1} {AI12-0003-1} If the pragma is used as a configuration
pragma, the storage_pool_indicator shall be either null or Standard, and it
defines the default pool to be the given storage_pool_indicator within all
applicable compilation units (see 10.1.5), except within the immediate scope
of another pragma Default_Storage_Pool. Otherwise, [the pragma occurs
immediately within a sequence of declarations, and] it defines the default
pool within the immediate scope of the pragma to be the given
storage_pool_indicator, except within the immediate scope of a later pragma
Default_Storage_Pool. [Thus, an inner pragma overrides an outer one.]

4.3/4 {AI05-0190-1} {AI05-0262-1} A pragma Default_Storage_Pool shall not be
used as a configuration pragma that applies to a compilation unit that is
within the immediate scope of another pragma Default_Storage_Pool.

4.a/3       Reason: This is to prevent confusion in cases like this:

4.b/3           package Parent is
                   pragma Default_Storage_Pool(...);
                   ...
                end Parent;

4.c/3           pragma Default_Storage_Pool(...); -- Illegal!
                package Parent.Child is
                   ...
                end Parent.Child;

4.d/3       where the Default_Storage_Pool on Parent.Child would not (if it
            were legal) override the one in Parent.


                              Static Semantics

5/4 {AI05-0190-1} {AI05-0229-1} {AI12-0003-1} The language-defined aspect
Default_Storage_Pool may be specified for a generic instance; it defines the
default pool for access types within an instance. .

5.1/4 {AI12-0003-1} The Default_Storage_Pool aspect may be specified as
Standard, which is an identifier specific to an aspect (see 13.1.1) and
defines the default pool to be Standard. In this case, there shall not be a
declaration with defining_identifier Standard that is immediately visible at
the point of the aspect specification, other than package Standard itself.

5.2/4 {AI12-0003-1} Otherwise, the expected type for the Default_Storage_Pool
aspect is Root_Storage_Pool'Class and the aspect_definition shall be a name
that denotes a variable. This aspect overrides any Default_Storage_Pool pragma
that might apply to the generic unit; if the aspect is not specified, the
default pool of the instance is that defined for the generic unit.

5.a/3       Aspect Description for Default_Storage_Pool: Default storage pool
            for a generic instance.

5.3/4 {AI12-0136-1} The effect of specifying the aspect Default_Storage_Pool
on an instance of a language-defined generic unit is implementation-defined.

5.a.1/4     Implementation defined: The effect of specifying aspect
            Default_Storage_Pool on an instance of a language-defined generic
            unit.

6/3 {AI05-0190-1} {AI05-0229-1} For nonderived access types declared in places
where the default pool is defined by the pragma or aspect, their Storage_Pool
or Storage_Size attribute is determined as follows, unless Storage_Pool or
Storage_Size is specified for the type:

6.1/3   * {AI05-0190-1} If the default pool is null, the Storage_Size
        attribute is defined by the language to be zero. [Therefore, an
        allocator for such a type is illegal.]

6.2/4   * {AI05-0190-1} {AI12-0003-1} If the default pool is neither null nor
        Standard, the Storage_Pool attribute is that pool.

6.3/4 {AI05-0190-1} {AI12-0003-1} Otherwise (including when the default pool
is specified as Standard), the standard storage pool is used for the type as
described in 13.11.

6.a/3       Ramification: {AI05-0190-1} {AI05-0229-1} Default_Storage_Pool is
            the only way to specify the storage pool for an anonymous access
            type.

6.b/3       {AI05-0190-1} {AI05-0229-1} Note that coextensions should be
            allocated in the same pool (or on the stack) as the outer object
            (see 13.11); the Storage_Pool of the access discriminant (and
            hence the Default_Storage_Pool) is supposed to be ignored for
            coextensions. This matches the required finalization point for
            coextensions.

6.b.1/3     {AI05-0190-1} The default storage pool for an allocator that
            occurs within an instance of a generic is defined by the
            Default_Storage_Pool aspect of the instantiation (if specified),
            or by the Default_Storage_Pool pragma that applied to the generic;
            the Default_Storage_Pool pragma that applies to the instantiation
            is irrelevant.

6.b.2/3     {AI05-0190-1} It is possible to specify the Default_Storage_Pool
            aspect for an instantiation such that allocations will fail. For
            example, the generic unit might be expecting a pool that supports
            certain sizes and alignments, and the one on the instance might be
            more restrictive. It is the programmer's responsibility to get
            this right.

6.b.3/3     {AI05-0190-1} The semantics of the Default_Storage_Pool aspect are
            similar to passing a pool object as a generic formal, and putting
            pragma Default_Storage_Pool at the top of the generic's visible
            part, specifying that formal.

7/3 This paragraph was deleted.{AI05-0229-1}


                         Implementation Permissions

8/3 {AI05-0190-1} {AI05-0229-1} An object created by an allocator that is
passed as the actual parameter to an access parameter may be allocated on the
stack, and automatically reclaimed, regardless of the default pool.

8.a/3       Discussion: {AI05-0190-1} This matches the required finalization
            point for such an allocated object.

        NOTES

9/3     32  {AI05-0190-1} Default_Storage_Pool may be used with restrictions
        No_Coextensions and No_Access_Parameter_Allocators (see H.4) to ensure
        that all allocators use the default pool.


                         Wording Changes from Ada 83

9.a/3       This paragraph was deleted.{AI05-0229-1}


                       Incompatibilities With Ada 2005

9.b/3       {AI05-0229-1} Pragma Controlled has been dropped from Ada, as it
            has no effect in any known Ada implementations and it seems to
            promise capabilities not expected in Ada implementations. This is
            usually not an incompatibility, as the pragma merely becomes
            unrecognized (with a warning) and can be implemented as an
            implementation-defined pragma if desired. However, it is
            incompatible if it is (now) implemented as an
            implementation-defined pragma, someone used this pragma in a unit,
            and they also used restriction No_Implementation_Pragmas on that
            unit. In that case, the pragma would now violate the restriction;
            but use of this pragma (which does nothing) should be very rare,
            so this is not a significant issue.


                           Extensions to Ada 2005

9.c/4       {AI05-0190-1} {AI12-0005-1} The pragma Default_Storage_Pool and
            aspect Default_Storage_Pool are new.


                        Wording Changes from Ada 2005

9.d/3       {AI05-0229-1} The entire discussion of garbage collection (and
            especially that of controlled objects) is deleted. Ada 2012
            provides subpools (see 13.11.4) for storage management of objects,
            including controlled objects, a mechanism which is much more
            predictable than garbage collection. Note that no version of Ada
            allows early finalization of controlled objects (other than via
            the use of Unchecked_Deallocation or
            Unchecked_Deallocate_Subpool), so that garbage collection of such
            objects would be ineffective in the standard mode anyway.


                           Extensions to Ada 2012

9.e/4       {AI05-0003-1} Corrigendum: The storage_pool_indicator Standard is
            new.


                        Wording Changes from Ada 2012

9.f/4       {AI12-0136-1} Corrigendum: We now explicitly say that the behavior
            of language-defined generic units when given the
            Default_Storage_Pool aspect is implementation-defined. Portable
            code cannot rely on such a package using a particular pool
            implementation.


13.11.4 Storage Subpools


1/3 {AI05-0111-3} This subclause defines a package to support the partitioning
of a storage pool into subpools. A subpool may be specified as the default to
be used for allocation from the associated storage pool, or a particular
subpool may be specified as part of an allocator (see 4.8).


                              Static Semantics

2/3 {AI05-0111-3} The following language-defined library package exists:

3/3     package System.Storage_Pools.Subpools is
           pragma Preelaborate (Subpools);

4/3        type Root_Storage_Pool_With_Subpools is
              abstract new Root_Storage_Pool with private;

5/3        type Root_Subpool is abstract tagged limited private;

6/3        type Subpool_Handle is access all Root_Subpool'Class;
           for Subpool_Handle'Storage_Size use 0;

7/3        function Create_Subpool
         (Pool : in out Root_Storage_Pool_With_Subpools)
              return not null Subpool_Handle is abstract;

8/3     {AI05-0252-1}
           -- The following operations are intended for pool implementers:

9/3        function Pool_of_Subpool (Subpool : not null Subpool_Handle)
              return access Root_Storage_Pool_With_Subpools'Class;

10/3       procedure Set_Pool_of_Subpool (
              Subpool : in not null Subpool_Handle;
              To : in out Root_Storage_Pool_With_Subpools'Class);

11/3       procedure Allocate_From_Subpool (
              Pool : in out Root_Storage_Pool_With_Subpools;
              Storage_Address : out Address;
              Size_In_Storage_Elements : in Storage_Elements.Storage_Count;
              Alignment : in Storage_Elements.Storage_Count;
              Subpool : in not null Subpool_Handle) is abstract
                 with Pre'Class => Pool_of_Subpool(Subpool) = Pool'Access;

12/3       procedure Deallocate_Subpool (
              Pool : in out Root_Storage_Pool_With_Subpools;
              Subpool : in out Subpool_Handle) is abstract
                 with Pre'Class => Pool_of_Subpool(Subpool) = Pool'Access;

13/3    {AI05-0298-1}    function Default_Subpool_for_Pool (
              Pool : in out Root_Storage_Pool_With_Subpools)
                 return not null Subpool_Handle;

14/3       overriding
           procedure Allocate (
              Pool : in out Root_Storage_Pool_With_Subpools;
              Storage_Address : out Address;
              Size_In_Storage_Elements : in Storage_Elements.Storage_Count;
              Alignment : in Storage_Elements.Storage_Count);

15/3       overriding
           procedure Deallocate (
              Pool : in out Root_Storage_Pool_With_Subpools;
              Storage_Address : in Address;
              Size_In_Storage_Elements : in Storage_Elements.Storage_Count;
              Alignment : in Storage_Elements.Storage_Count) is null;

16/3    {AI05-0298-1}    overriding
           function Storage_Size (Pool : Root_Storage_Pool_With_Subpools)
              return Storage_Elements.Storage_Count
                  is (Storage_Elements.Storage_Count'Last);

17/3    private
           ... -- not specified by the language
        end System.Storage_Pools.Subpools;

18/3 {AI05-0111-3} A subpool is a separately reclaimable portion of a storage
pool, identified by an object of type Subpool_Handle (a subpool handle). A
subpool handle also identifies the enclosing storage pool, a storage pool that
supports subpools, which is a storage pool whose type is descended from
Root_Storage_Pool_With_Subpools. A subpool is created by calling
Create_Subpool or a similar constructor; the constructor returns the subpool
handle.

19/3 {AI05-0111-3} {AI05-0269-1} A subpool object is an object of a type
descended from Root_Subpool. [Typically, subpool objects are managed by the
containing storage pool; only the handles need be exposed to clients of the
storage pool. Subpool objects are designated by subpool handles, and are the
run-time representation of a subpool.]

19.a/3      Proof: We know that subpool handles designate subpool objects
            because the declaration of Subpool_Handle says so.

20/4 {AI05-0111-3} {AI05-0145-1} Each subpool belongs to a single storage pool
[(which will always be a pool that supports subpools)]. An access to the pool
that a subpool belongs to can be obtained by calling Pool_of_Subpool with the
subpool handle. Set_Pool_of_Subpool causes the subpool of the subpool handle
to belong to the given pool[; this is intended to be called from subpool
constructors like Create_Subpool.] Set_Pool_of_Subpool propagates
Program_Error if the subpool already belongs to a pool. If Set_Pool_of_Subpool
has not yet been called for a subpool, Pool_of_Subpool returns null.

20.a/3      Discussion: Pool_of_Subpool and Set_Pool_of_Subpool are provided
            by the Ada implementation and typically will not be overridden by
            the pool implementer.

21/3 {AI05-0111-3} When an allocator for a type whose storage pool supports
subpools is evaluated, a call is made on Allocate_From_Subpool passing in a
Subpool_Handle, in addition to the parameters as defined for calls on Allocate
(see 13.11). The subpool designated by the subpool_handle_name is used, if
specified in an allocator. Otherwise, Default_Subpool_for_Pool of the Pool is
used to provide a subpool handle. All requirements on the Allocate procedure
also apply to Allocate_from_Subpool.

21.a/3      Discussion: Deallocate_Subpool is expected to do whatever is
            needed to deallocate all of the objects contained in the subpool;
            it is called from Unchecked_Deallocate_Subpool (see 13.11.5).

21.b/3      Typically, the pool implementer will not override Allocate. In the
            canonical definition of the language, it will never be called for
            a pool that supports subpools (there is an
            Implementation Permission below that allows it to be called in
            certain rare cases).


                               Legality Rules

22/3 {AI05-0111-3} If a storage pool that supports subpools is specified as
the Storage_Pool for an access type, the access type is called a subpool
access type. A subpool access type shall be a pool-specific access type.

23/3 {AI05-0111-3} {AI05-0252-1} The accessibility level of a subpool access
type shall not be statically deeper than that of the storage pool object. If
the specified storage pool object is a storage pool that supports subpools,
then the name that denotes the object shall not denote part of a formal
parameter, nor shall it denote part of a dereference of a value of a
non-library-level general access type. In addition to the places where
Legality Rules normally apply (see 12.3), these rules also apply in the
private part of an instance of a generic unit.


                              Dynamic Semantics

24/3 {AI05-0111-3} {AI05-0252-1} When an access type with a specified storage
pool is frozen (see 13.14), if the tag of the storage pool object identifies a
storage pool that supports subpools, the following checks are made:

25/3   * the name used to specify the storage pool object does not denote part
        of a formal parameter nor part of a dereference of a value of a
        non-library-level general access type; and

26/3   * the accessibility level of the access type is not deeper than that of
        the storage pool object.

27/3 {AI05-0252-1} Program_Error is raised if either of these checks fail.

27.a/3      Reason: This check (and its static counterpart) ensures that the
            type of the allocated objects exists at least as long as the
            storage pool object, so that the subpools are finalized (which
            finalizes any remaining allocated objects) before the type of the
            objects ceases to exist. The access type itself (and the
            associated collection) will cease to exist before the storage pool
            ceases to exist.

27.b/3      We also disallow the use of formal parameters and dereferences of
            non-library-level general access types when specifying a storage
            pool object if it supports subpools, because the "apparent"
            accessibility level is potentially deeper than that of the
            underlying object. Neither of these cases is very likely to occur
            in practice.

28/3 {AI05-0111-3} A call to Subpools.Allocate(P, Addr, Size, Align) does the
following:

29/3    Allocate_From_Subpool
          (Root_Storage_Pool_With_Subpools'Class(P),
           Addr, Size, Align,
           Subpool => Default_Subpool_for_Pool
                        (Root_Storage_Pool_With_Subpools'Class(P)));

30/3 {AI05-0111-3} An allocator that allocates in a subpool raises
Program_Error if the allocated object has task parts.

30.a/3      Reason: This is to ease implementation. We envision relaxing this
            restriction in a future version of Ada, once implementation
            experience has been gained. At this time, we are unable to come up
            with a set of rules for task termination that is both useful, and
            surely feasible to implement.

31/3 {AI05-0111-3} Unless overridden, Default_Subpool_for_Pool propagates
Program_Error.


                             Erroneous Execution

31.1/4 {AI12-0142-1} If Allocate_From_Subpool does not meet one or more of the
requirements on the Allocate procedure as given in the Erroneous Execution
rules of 13.11, then the program execution is erroneous.


                         Implementation Permissions

32/3 {AI05-0111-3} When an allocator for a type whose storage pool is of type
Root_Storage_Pool'Class is evaluated, but supports subpools, the
implementation may call Allocate rather than Allocate_From_Subpool. [This will
have the same effect, so long as Allocate has not been overridden.]

32.a/3      Reason: This ensures either of two implementation models are
            possible for an allocator with no subpool_specification. Note that
            the "supports subpools" property is not known at compile time for
            a pool of the class-wide type.

32.b/3        * The implementation can dispatch to Storage_Pools.Allocate. If
                the pool supports subpools, this will call
                Allocate_From_Subpool with the default subpool so long as
                Allocate has not been overridden.

32.c/3        * The implementation can declare Allocate_From_Subpool as a
                primitive of Root_Storage_Pool in the private part of
                Storage_Pools. This means that the Allocate_From_Subpool for
                Root_Storage_Pool_With_Subpools overrides that private one.
                The implementation can thus call the private one, which will
                call Allocate for non-subpool-supporting pools. The effect of
                this implementation does not change if Allocate is overridden
                for a pool that supports subpools.

        NOTES

33/3    33  {AI05-0111-3} A user-defined storage pool type that supports
        subpools can be implemented by extending the
        Root_Storage_Pool_With_Subpools type, and overriding the primitive
        subprograms Create_Subpool, Allocate_From_Subpool, and
        Deallocate_Subpool. Create_Subpool should call Set_Pool_Of_Subpool
        before returning the subpool handle. To make use of such a pool, a
        user would declare an object of the type extension, use it to define
        the Storage_Pool attribute of one or more access types, and then call
        Create_Subpool to obtain subpool handles associated with the pool.

34/3    34  {AI05-0111-3} A user-defined storage pool type that supports
        subpools may define additional subpool constructors similar to
        Create_Subpool (these typically will have additional parameters).

35/3    35  {AI05-0111-3} The pool implementor should override
        Default_Subpool_For_Pool if the pool is to support a default subpool
        for the pool. The implementor can override Deallocate if individual
        object reclamation is to be supported, and can override Storage_Size
        if there is some limit on the total size of the storage pool. The
        implementor can override Initialize and Finalize if there is any need
        for nontrivial initialization and finalization for the pool as a
        whole. For example, Finalize might reclaim blocks of storage that are
        allocated over and above the space occupied by the pool object itself.
        The pool implementor may extend the Root_Subpool type as necessary to
        carry additional information with each subpool provided by
        Create_Subpool.


                           Extensions to Ada 2005

35.a/3      {AI05-0111-3} {AI05-0252-1} Subpools and the package
            System.Storage_Pools.Subpools are new.


                        Wording Changes from Ada 2012

35.b/4      {AI12-0142-1} Corrigendum: Clarified that an incorrect
            implementation of Allocate_From_Subpool causes execution to become
            erroneous. The wording already said that the requirements of
            Allocate apply to Allocate_From_Subpool, so we're just confirming
            the consequences of violating those requirements also apply.

35.c/4      {AI12-0145-1} Corrigendum: Clarified that Pool_of_Subpool returns
            null if Set_Pool_of_Subpool has not been called. As that can be
            inferred from the definition, and all known existing
            implementations return null in this case, we document this as a
            wording change rather than a possible inconsistency.


13.11.5 Subpool Reclamation


1/3 {AI05-0111-3} A subpool may be explicitly deallocated using
Unchecked_Deallocate_Subpool.


                              Static Semantics

2/3 {AI05-0111-3} The following language-defined library procedure exists:

3/3     with System.Storage_Pools.Subpools;
        procedure Ada.Unchecked_Deallocate_Subpool
           (Subpool : in out System.Storage_Pools.Subpools.Subpool_Handle);

4/3 {AI05-0111-3} If Subpool is null, a call on Unchecked_Deallocate_Subpool
has no effect. Otherwise, the subpool is finalized, and Subpool is set to null.

5/3 {AI05-0111-3} Finalization of a subpool has the following effects:

6/3   * The subpool no longer belongs to any pool;

7/3   * Any of the objects allocated from the subpool that still exist are
        finalized in an arbitrary order;

7.1/4   * {AI12-0148-1} All of the objects allocated from the subpool cease to
        exist;

8/3   * The following [dispatching] call is then made:

9/3        Deallocate_Subpool(Pool_of_Subpool(Subpool).all, Subpool);

10/3 {AI05-0111-3} Finalization of a Root_Storage_Pool_With_Subpools object
finalizes all subpools that belong to that pool that have not yet been
finalized.

10.a/3      Discussion: There is no need to call Unchecked_Deallocation on an
            object allocated in a subpool. Such objects are deallocated all at
            once, when Unchecked_Deallocate_Subpool is called.

10.b/3      If Unchecked_Deallocation is called, the object is finalized, and
            then Deallocate is called on the Pool, which typically will do
            nothing. If it wants to free memory, it will need some way to get
            from the address of the object to the subpool.

10.c/3      There is no Deallocate_From_Subpool. There is no efficient way for
            the implementation to determine the subpool for an arbitrary
            object, and if the pool implementer can determinate that, they can
            use that as part of the implementation of Deallocate.

10.d/3      If Unchecked_Deallocation is not called (the usual case), the
            object will be finalized when Unchecked_Deallocate_Subpool is
            called.

10.e/3      If that's never called, then the object will be finalized when the
            Pool_With_Subpools is finalized (by permission - it might happen
            when the collection of the access type is finalized).


                           Extensions to Ada 2005

10.f/3      {AI05-0111-3} Unchecked_Deallocate_Subpool is new.


                        Wording Changes from Ada 2012

10.g/4      {AI12-0148-1} Corrigendum: Added missing wording to state that the
            objects cease to exist after the completion of finalization. This
            is formally an inconsistency (it would be possible to depend on
            the fact that objects finalized by Unchecked_Deallocate_Subpool
            still exist), but that violates every sane expectation for a
            procedure called "Deallocate" something.


13.11.6 Storage Subpool Example



                                  Examples

1/3 {AI05-0111-3} The following example is a simple but complete
implementation of the classic Mark/Release pool using subpools:

2/3     with System.Storage_Pools.Subpools;
        with System.Storage_Elements;
        with Ada.Unchecked_Deallocate_Subpool;
        package MR_Pool is

3/3        use System.Storage_Pools;
              -- For uses of Subpools.
           use System.Storage_Elements;
              -- For uses of Storage_Count and Storage_Array.

4/3        -- Mark and Release work in a stack fashion, and allocations are not allowed
           -- from a subpool other than the one at the top of the stack. This is also
           -- the default pool.

5/3        subtype Subpool_Handle is Subpools.Subpool_Handle;

6/3        type Mark_Release_Pool_Type (Pool_Size : Storage_Count) is new
              Subpools.Root_Storage_Pool_With_Subpools with private;

7/3        function Mark (Pool : in out Mark_Release_Pool_Type)
              return not null Subpool_Handle;

8/3        procedure Release (Subpool : in out Subpool_Handle) renames
              Ada.Unchecked_Deallocate_Subpool;

9/3     private

10/3       type MR_Subpool is new Subpools.Root_Subpool with record
              Start : Storage_Count;
           end record;
           subtype Subpool_Indexes is Positive range 1 .. 10;
           type Subpool_Array is array (Subpool_Indexes) of aliased MR_Subpool;

11/4    {AI05-0298-1} {AI12-0134-1}
           type Mark_Release_Pool_Type (Pool_Size : Storage_Count) is new
              Subpools.Root_Storage_Pool_With_Subpools with record
              Storage         : Storage_Array (0 .. Pool_Size);
              Next_Allocation : Storage_Count := 0;
              Markers         : Subpool_Array;
              Current_Pool    : Subpool_Indexes := 1;
           end record;

12/3    {AI05-0298-1}    overriding
           function Create_Subpool (Pool : in out Mark_Release_Pool_Type)
              return not null Subpool_Handle;

13/3       function Mark (Pool : in out Mark_Release_Pool_Type)
              return not null Subpool_Handle renames Create_Subpool;

14/3       overriding
           procedure Allocate_From_Subpool (
              Pool : in out Mark_Release_Pool_Type;
              Storage_Address : out System.Address;
              Size_In_Storage_Elements : in Storage_Count;
              Alignment : in Storage_Count;
              Subpool : not null Subpool_Handle);

15/3       overriding
           procedure Deallocate_Subpool (
              Pool : in out Mark_Release_Pool_Type;
              Subpool : in out Subpool_Handle);

16/3    {AI05-0298-1}    overriding
           function Default_Subpool_for_Pool (Pool : in out Mark_Release_Pool_Type)
              return not null Subpool_Handle;

17/3       overriding
           procedure Initialize (Pool : in out Mark_Release_Pool_Type);

18/3       -- We don't need Finalize.

19/3    end MR_Pool;

20/3    package body MR_Pool is

21/3    {AI05-0298-1}    use type Subpool_Handle;

22/3    {AI05-0298-1}
           procedure Initialize (Pool : in out Mark_Release_Pool_Type) is
              -- Initialize the first default subpool.
           begin
              Pool.Markers(1).Start := 1;
              Subpools.Set_Pool_of_Subpool
                 (Pool.Markers(1)'Unchecked_Access, Pool);
           end Initialize;

23/3       function Create_Subpool (Pool : in out Mark_Release_Pool_Type)
              return not null Subpool_Handle is
              -- Mark the current allocation location.
           begin
              if Pool.Current_Pool = Subpool_Indexes'Last then
                 raise Storage_Error; -- No more subpools.
              end if;
              Pool.Current_Pool := Pool.Current_Pool + 1; -- Move to the next subpool

24/3    {AI05-0298-1}       return Result : constant not null Subpool_Handle :=
                 Pool.Markers(Pool.Current_Pool)'Unchecked_Access
              do
                 Pool.Markers(Pool.Current_Pool).Start := Pool.Next_Allocation;
                 Subpools.Set_Pool_of_Subpool (Result, Pool);
              end return;
           end Create_Subpool;

25/3    {AI05-0298-1}    procedure Deallocate_Subpool (
              Pool : in out Mark_Release_Pool_Type;
              Subpool : in out Subpool_Handle) is
           begin
              if Subpool /= Pool.Markers(Pool.Current_Pool)'Unchecked_Access then
                 raise Program_Error; -- Only the last marked subpool can be released.
              end if;
              if Pool.Current_Pool /= 1 then
                 Pool.Next_Allocation := Pool.Markers(Pool.Current_Pool).Start;
                 Pool.Current_Pool := Pool.Current_Pool - 1; -- Move to the previous subpool
              else -- Reinitialize the default subpool:
                 Pool.Next_Allocation := 1;
                 Subpools.Set_Pool_of_Subpool
                    (Pool.Markers(1)'Unchecked_Access, Pool);
              end if;
           end Deallocate_Subpool;

26/3    {AI05-0298-1}
           function Default_Subpool_for_Pool (Pool : in out Mark_Release_Pool_Type)
              return not null Subpool_Handle is
           begin
              return Pool.Markers(Pool.Current_Pool)'Unchecked_Access;
           end Default_Subpool_for_Pool;

27/3       procedure Allocate_From_Subpool (
              Pool : in out Mark_Release_Pool_Type;
              Storage_Address : out System.Address;
              Size_In_Storage_Elements : in Storage_Count;
              Alignment : in Storage_Count;
              Subpool : not null Subpool_Handle) is
           begin
              if Subpool /= Pool.Markers(Pool.Current_Pool)'Unchecked_Access then
                 raise Program_Error; -- Only the last marked subpool can be used for allocations.
              end if;

28/4    {AI12-0080-1}
              -- Check for the maximum supported alignment, which is the alignment of the storage area:
              if Alignment > Pool.Storage'Alignment then
                 raise Program_Error;
              end if;
              -- Correct the alignment if necessary:
              Pool.Next_Allocation := Pool.Next_Allocation +
                 ((-Pool.Next_Allocation) mod Alignment);
              if Pool.Next_Allocation + Size_In_Storage_Elements >
                 Pool.Pool_Size then
                 raise Storage_Error; -- Out of space.
              end if;
              Storage_Address := Pool.Storage (Pool.Next_Allocation)'Address;
              Pool.Next_Allocation :=
                 Pool.Next_Allocation + Size_In_Storage_Elements;
           end Allocate_From_Subpool;

29/3    end MR_Pool;


                        Wording Changes from Ada 2005

29.a/3      {AI05-0111-3} This example of subpools is new.


13.12 Pragma Restrictions and Pragma Profile


1/3 {AI05-0246-1} [A pragma Restrictions expresses the user's intent to abide
by certain restrictions. A pragma Profile expresses the user's intent to abide
by a set of Restrictions or other specified run-time policies. These may
facilitate the construction of simpler run-time environments.]


                                   Syntax

2       The form of a pragma Restrictions is as follows:

3         pragma Restrictions(restriction{, restriction});

4/2     {AI95-00381-01} restriction ::= restriction_identifier
            | restriction_parameter_identifier
         => restriction_parameter_argument

4.1/2   {AI95-00381-01} restriction_parameter_argument ::= name
         | expression


                            Name Resolution Rules

5   Unless otherwise specified for a particular restriction, the expression is
expected to be of any integer type.


                               Legality Rules

6   Unless otherwise specified for a particular restriction, the expression
shall be static, and its value shall be nonnegative.

7.a/3       This paragraph was deleted.

Paragraph 7 was deleted.


                           Post-Compilation Rules

8/3 {AI05-0013-1} A pragma Restrictions is a configuration pragma. If a
pragma Restrictions applies to any compilation unit included in the partition,
this may impose either (or both) of two kinds of requirements, as specified
for the particular restriction:

8.1/3   * {AI05-0013-1} A restriction may impose requirements on some or all
        of the units comprising the partition. Unless otherwise specified for
        a particular restriction, such a requirement applies to all of the
        units comprising the partition and is enforced via a post-compilation
        check.

8.2/3   * {AI05-0013-1} A restriction may impose requirements on the run-time
        behavior of the program, as indicated by the specification of run-time
        behavior associated with a violation of the requirement.

8.a.1/3     Ramification: In this latter case, there is no post-compilation
            check needed for the requirement.

8.3/1 {8652/0042} {AI95-00130-01} For the purpose of checking whether a
partition contains constructs that violate any restriction (unless specified
otherwise for a particular restriction):

8.4/1   * {8652/0042} {AI95-00130-01} Generic instances are logically expanded
        at the point of instantiation;

8.5/1   * {8652/0042} {AI95-00130-01} If an object of a type is declared or
        allocated and not explicitly initialized, then all expressions
        appearing in the definition for the type and any of its ancestors are
        presumed to be used;

8.6/1   * {8652/0042} {AI95-00130-01} A default_expression for a formal
        parameter or a generic formal object is considered to be used if and
        only if the corresponding actual parameter is not provided in a given
        call or instantiation.


                         Implementation Permissions

8.7/3 {AI05-0269-1} An implementation may provide implementation-defined
restrictions; the identifier for an implementation-defined restriction shall
differ from those of the language-defined restrictions.

8.a.2/3     Implementation defined: Implementation-defined restrictions
            allowed in a pragma Restrictions.

9   An implementation may place limitations on the values of the expression
that are supported, and limitations on the supported combinations of
restrictions. The consequences of violating such limitations are
implementation defined.

9.a         Implementation defined: The consequences of violating limitations
            on Restrictions pragmas.

9.b         Ramification: Such limitations may be enforced at compile time or
            at run time. Alternatively, the implementation is allowed to
            declare violations of the restrictions to be erroneous, and not
            enforce them at all.

9.1/1 {8652/0042} {AI95-00130-01} An implementation is permitted to omit
restriction checks for code that is recognized at compile time to be
unreachable and for which no code is generated.

9.2/1 {8652/0043} {AI95-00190-01} Whenever enforcement of a restriction is not
required prior to execution, an implementation may nevertheless enforce the
restriction prior to execution of a partition to which the restriction
applies, provided that every execution of the partition would violate the
restriction.


                                   Syntax

10/3    {AI95-00249-01} {AI05-0246-1} The form of a pragma Profile is as
        follows:

11/3      pragma Profile (profile_identifier {,
        profile_pragma_argument_association});


                               Legality Rules

12/3 {AI95-00249-01} {AI05-0246-1} The profile_identifier shall be the name of
a usage profile. The semantics of any profile_pragma_argument_associations are
defined by the usage profile specified by the profile_identifier.


                              Static Semantics

13/3 {AI95-00249-01} {AI05-0246-1} A profile is equivalent to the set of
configuration pragmas that is defined for each usage profile.


                           Post-Compilation Rules

14/3 {AI95-00249-01} A pragma Profile is a configuration pragma. There may be
more than one pragma Profile for a partition.


                         Implementation Permissions

15/3 {AI05-0269-1} An implementation may provide implementation-defined usage
profiles; the identifier for an implementation-defined usage profile shall
differ from those of the language-defined usage profiles.

15.a.1/3    Implementation defined: Implementation-defined usage profiles
            allowed in a pragma Profile.

        NOTES

16/2    36  {AI95-00347-01} Restrictions intended to facilitate the
        construction of efficient tasking run-time systems are defined in
        D.7. Restrictions intended for use when constructing high integrity
        systems are defined in H.4.

17      37  An implementation has to enforce the restrictions in cases where
        enforcement is required, even if it chooses not to take advantage of
        the restrictions in terms of efficiency.

17.a        Discussion: It is not the intent that an implementation will
            support a different run-time system for every possible combination
            of restrictions. An implementation might support only two run-time
            systems, and document a set of restrictions that is sufficient to
            allow use of the more efficient and safe one.


                            Extensions to Ada 83

17.b        Pragma Restrictions is new to Ada 95.


                            Extensions to Ada 95

17.c/3      {AI95-00249-01} {AI05-0246-1} Pragma Profile is new; it was moved
            here by Ada 2012 and renamed to a "usage profile" but was
            otherwise unchanged.


                         Wording Changes from Ada 95

17.d/2      {8652/0042} {AI95-00130-01} Corrigendum: Corrected the wording so
            that restrictions are checked inside of generic instantiations and
            in default expressions. Since not making these checks would
            violate the purpose of restrictions, we are not documenting this
            as an incompatibility.

17.e/2      {8652/0043} {AI95-00190-01} Corrigendum: Added a permission that
            restrictions can be enforced at compile-time. While this is
            technically incompatible, documenting it as such would be
            unnecessarily alarming - there should not be any programs
            depending on the runtime failure of restrictions.

17.f/2      {AI95-00381-01} The syntax of a restriction_parameter_argument has
            been defined to better support restriction No_Dependence (see
            13.12.1).


                        Wording Changes from Ada 2005

17.g/3      {AI05-0013-1} Correction: When restrictions are checked has been
            clarified.


13.12.1 Language-Defined Restrictions and Profiles



                              Static Semantics

1/2 {AI95-00257-01} The following restriction_identifiers are language defined
(additional restrictions are defined in the Specialized Needs Annexes):

1.1/3 {AI05-0241-1} No_Implementation_Aspect_Specifications
                There are no implementation-defined aspects specified by an
                aspect_specification. This restriction applies only to the
                current compilation or environment, not the entire partition.

1.a/3       Discussion: {AI05-0241-1} This restriction (as well as others
            below) applies only to the current compilation, because it is
            likely that the runtime (and possibly user-written low-level code)
            will need to use implementation-defined aspects. But a
            partition-wide restriction applies everywhere, including the
            runtime.

2/2 {AI95-00257-01} No_Implementation_Attributes
                There are no implementation-defined attributes. This
                restriction applies only to the current compilation or
                environment, not the entire partition.

2.1/3 {AI05-0246-1} {AI05-0269-1} No_Implementation_Identifiers
                There are no usage names that denote declarations with
                implementation-defined identifiers that occur within
                language-defined packages or instances of language-defined
                generic packages. Such identifiers can arise as follows:

2.2/3             * The following language-defined packages and generic
                    packages allow implementation-defined identifiers:

2.3/3                 * package System (see 13.7);

2.4/3                 * package Standard (see A.1);

2.5/3                 * package Ada.Command_Line (see A.15);

2.6/3                 * package Interfaces.C (see B.3);

2.7/3                 * package Interfaces.C.Strings (see B.3.1);

2.8/3                 * package Interfaces.C.Pointers (see B.3.2);

2.9/3                 * package Interfaces.COBOL (see B.4);

2.10/3                * package Interfaces.Fortran (see B.5);

2.11/3            * The following language-defined packages contain only
                    implementation-defined identifiers:

2.12/3                * package System.Machine_Code (see 13.8);

2.13/3                * package Ada.Directories.Information (see A.16);

2.14/3                * nested Implementation packages of the Queue containers
                        (see A.18.28-31);

2.15/3                * package Interfaces (see B.2);

2.16/3                * package Ada.Interrupts.Names (see C.3.2).

2.17/3          For package Standard, Standard.Long_Integer and
                Standard.Long_Float are considered language-defined
                identifiers, but identifiers such as
                Standard.Short_Short_Integer are considered
                implementation-defined.

2.18/3          This restriction applies only to the current compilation or
                environment, not the entire partition.

3/2 {AI95-00257-01} No_Implementation_Pragmas
                There are no implementation-defined pragmas or pragma
                arguments. This restriction applies only to the current
                compilation or environment, not the entire partition.

3.1/3 {AI05-0242-1} No_Implementation_Units
                There is no mention in the context_clause of any
                implementation-defined descendants of packages Ada,
                Interfaces, or System. This restriction applies only to the
                current compilation or environment, not the entire partition.

4/3 {AI95-00368-01} {AI05-0229-1} No_Obsolescent_Features
                There is no use of language features defined in Annex J. It is
                implementation defined whether uses of the renamings of J.1
                and of the pragmas of J.15 are detected by this restriction.
                This restriction applies only to the current compilation or
                environment, not the entire partition.

4.a/2       Reason: A user could compile a rename like

4.b/2           with Ada.Text_IO;
                package Text_IO renames Ada.Text_IO;

4.c/2       Such a rename must not be disallowed by this restriction, nor
            should the compilation of such a rename be restricted by an
            implementation. Many implementations implement the renames of
            J.1 by compiling them normally; we do not want to require
            implementations to use a special mechanism to implement these
            renames.

4.d/3       {AI05-0229-1} The pragmas have the same functionality as the
            corresponding aspect (unlike the typical obsolescent feature), and
            rejecting them could be a significant portability problem for
            existing code.

5/3 {AI95-00381-01} {AI05-0241-1} The following
restriction_parameter_identifiers are language defined:

6/2 {AI95-00381-01} No_Dependence
                Specifies a library unit on which there are no semantic
                dependences.

6.1/3 {AI05-0241-1} No_Specification_of_Aspect
                Identifies an aspect for which no aspect_specification,
                attribute_definition_clause, or pragma is given.

6.2/3 {AI05-0272-1} No_Use_Of_Attribute
                Identifies an attribute for which no attribute_reference or
                attribute_definition_clause is given.

6.3/3 {AI05-0272-1} No_Use_Of_Pragma
                Identifies a pragma which is not to be used.


                               Legality Rules

7/2 {AI95-00381-01} The restriction_parameter_argument of a No_Dependence
restriction shall be a name; the name shall have the form of a full expanded
name of a library unit, but need not denote a unit present in the environment.

7.a/2       Ramification: This name is not resolved.

7.1/3 {AI05-0241-1} The restriction_parameter_argument of a
No_Specification_of_Aspect restriction shall be an identifier; this is an
identifier specific to a pragma (see 2.8) and does not denote any declaration.

7.b/3       Ramification: This restriction_parameter_argument is not resolved
            as it is an identifier specific to a pragma. As for No_Dependence,
            there is no check that the aspect identifier is meaningful; it
            might refer to an implementation-defined aspect on one
            implementation, but nothing at all on another implementation.

7.2/3 {AI05-0272-1} The restriction_parameter_argument of a
No_Use_Of_Attribute restriction shall be an identifier or one of the reserved
words Access, Delta, Digits, Mod, or Range; this is an identifier specific to
a pragma.

7.c/3       Ramification: This restriction_parameter_argument is not resolved
            as it is an identifier specific to a pragma. There is no check
            that the attribute identifier refers to a known
            attribute_designator; it might refer to an implementation-defined
            attribute on one implementation, but nothing at all on another
            implementation.

7.3/3 {AI05-0272-1} The restriction_parameter_argument of a No_Use_Of_Pragma
restriction shall be an identifier or the reserved word Interface; this is an
identifier specific to a pragma.

7.d/3       Ramification: This restriction_parameter_argument is not resolved
            as it is an identifier specific to a pragma. There is no check
            that the pragma identifier refers to a known pragma; it might
            refer to an implementation-defined pragma on one implementation,
            but nothing at all on another implementation.


                           Post-Compilation Rules

8/3 {AI95-00381-01} {AI05-0241-1} No compilation unit included in the
partition shall depend semantically on the library unit identified by the
name of a No_Dependence restriction.

8.a/2       Ramification: There is no requirement that the library unit
            actually exist. One possible use of the pragma is to prevent the
            use of implementation-defined units; when the program is ported to
            a different compiler, it is perfectly reasonable that no unit with
            the name exist.


                              Static Semantics

9/3 {AI05-0246-1} The following profile_identifier is language defined:

10/3 {AI05-0246-1} No_Implementation_Extensions
                

11/3 {AI05-0246-1} For usage profile No_Implementation_Extensions, there shall
be no profile_pragma_argument_associations.

12/3 {AI05-0246-1} The No_Implementation_Extensions usage profile is
equivalent to the following restrictions:

13/3    No_Implementation_Aspect_Specifications,
        No_Implementation_Attributes,
        No_Implementation_Identifiers,
        No_Implementation_Pragmas,
        No_Implementation_Units.


                            Extensions to Ada 95

13.a/2      {AI95-00257-01} {AI95-00368-01} Restrictions
            No_Implementation_Attributes, No_Implementation_Pragmas, and
            No_Obsolescent_Features are new.

13.b/2      {AI95-00381-01} Restriction No_Dependence is new.


                           Extensions to Ada 2005

13.c/3      {AI05-0241-1} {AI05-0242-1} {AI05-0246-1} {AI05-0272-1}
            Restrictions No_Implementation_Aspect_Specifications,
            No_Implementation_Identifiers, No_Implementation_Units,
            No_Specification_of_Aspect, No_Use_of_Attribute, and
            No_Use_of_Pragma are new.

13.d/3      {AI05-0246-1} Profile No_Implementation_Extensions is new.


13.13 Streams


1   A stream is a sequence of elements comprising values from possibly
different types and allowing sequential access to these values. A stream type
is a type in the class whose root type is Streams.Root_Stream_Type. A stream
type may be implemented in various ways, such as an external sequential file,
an internal buffer, or a network channel.

1.a         Discussion: A stream element will often be the same size as a
            storage element, but that is not required.

1.a.1/3     Glossary entry: A stream is a sequence of elements that can be
            used, along with the stream-oriented attributes, to support
            marshalling and unmarshalling of values of most types.


                            Extensions to Ada 83

1.b         Streams are new in Ada 95.


13.13.1 The Package Streams



                              Static Semantics

1   The abstract type Root_Stream_Type is the root type of the class of stream
types. The types in this class represent different kinds of streams. A new
stream type is defined by extending the root type (or some other stream type),
overriding the Read and Write operations, and optionally defining additional
primitive subprograms, according to the requirements of the particular kind of
stream. The predefined stream-oriented attributes like T'Read and T'Write make
dispatching calls on the Read and Write procedures of the Root_Stream_Type.
(User-defined T'Read and T'Write attributes can also make such calls, or can
call the Read and Write attributes of other types.)

2       package Ada.Streams is
            pragma Pure(Streams);

3/2     {AI95-00161-01}     type Root_Stream_Type
         is abstract tagged limited private;
            pragma Preelaborable_Initialization(Root_Stream_Type);

4/1     {8652/0044} {AI95-00181-01}     type Stream_Element
         is mod implementation-defined;
            type Stream_Element_Offset is range implementation-defined;
            subtype Stream_Element_Count is
                Stream_Element_Offset range 0..Stream_Element_Offset'Last;
            type Stream_Element_Array is
                array(Stream_Element_Offset range <>) of aliased Stream_Element;

5           procedure Read(
              Stream : in out Root_Stream_Type;
              Item   : out Stream_Element_Array;
              Last   : out Stream_Element_Offset) is abstract;

6           procedure Write(
              Stream : in out Root_Stream_Type;
              Item   : in Stream_Element_Array) is abstract;

7       private
           ... -- not specified by the language
        end Ada.Streams;

8/2 {AI95-00227-01} The Read operation transfers stream elements from the
specified stream to fill the array Item. Elements are transferred until
Item'Length elements have been transferred, or until the end of the stream is
reached. If any elements are transferred, the index of the last stream element
transferred is returned in Last. Otherwise, Item'First - 1 is returned in
Last. Last is less than Item'Last only if the end of the stream is reached.

9   The Write operation appends Item to the specified stream.

9.a/2       Discussion: {AI95-00114-01} The index subtype of
            Stream_Element_Array is Stream_Element_Offset because we wish to
            allow maximum flexibility. Most Stream_Element_Arrays will
            probably have a lower bound of 0 or 1, but other lower bounds,
            including negative ones, make sense in some situations.

9.b/3       {AI95-00114-01} {AI05-0005-1} Note that there are some
            language-defined subprograms that fill part of a
            Stream_Element_Array, and return the index of the last element
            filled as a Stream_Element_Offset. The Read procedures declared
            here, Streams.Stream_IO (see A.12.1), and System.RPC (see E.5)
            behave in this manner. These will raise Constraint_Error if the
            resulting Last value is not in Stream_Element_Offset. This implies
            that the Stream_Element_Array passed to these subprograms should
            not have a lower bound of Stream_Element_Offset'First, because
            then a read of 0 elements would always raise Constraint_Error. A
            better choice of lower bound is 0 or 1.


                         Implementation Permissions

9.1/1 {8652/0044} {AI95-00181-01} If Stream_Element'Size is not a multiple of
System.Storage_Unit, then the components of Stream_Element_Array need not be
aliased.

9.b.1/2     Ramification: {AI95-00114-01} If the Stream_Element'Size is less
            than the size of System.Storage_Unit, then components of Stream_-
            Element_Array need not be aliased. This is necessary as the
            components of type Stream_Element size might not be addressable on
            the target architecture.

        NOTES

10      38  See A.12.1, "The Package Streams.Stream_IO" for an example of
        extending type Root_Stream_Type.

11/2    39  {AI95-00227-01} If the end of stream has been reached, and
        Item'First is Stream_Element_Offset'First, Read will raise
        Constraint_Error.

11.a/2      Ramification: Thus, Stream_Element_Arrays should start at 0 or 1,
            not Stream_Element_Offset'First.


                            Extensions to Ada 95

11.b/2      {AI95-00161-01} Amendment Correction: Added pragma
            Preelaborable_Initialization to type Root_Stream_Type.


                         Wording Changes from Ada 95

11.c/2      {8652/0044} {AI95-00181-01} Corrigendum: Stream elements are
            aliased presuming that makes sense.

11.d/2      {AI95-00227-01} Fixed the wording for Read to properly define the
            result in Last when no stream elements are transfered.


13.13.2 Stream-Oriented Attributes


1/3 {8652/0009} {AI95-00137-01} {AI05-0183-1} The type-related operational
attributes Write, Read, Output, and Input convert values to a stream of
elements and reconstruct values from a stream.


                              Static Semantics

1.1/2 {AI95-00270-01} For every subtype S of an elementary type T, the
following representation attribute is defined:

1.2/3 S'Stream_Size
                {AI95-00270-01} {AI05-0194-1} Denotes the number of bits read
                from or written to a stream by the default implementations of
                S'Read and S'Write. Hence, the number of stream elements
                required per item of elementary type T is:

1.3/2               T'Stream_Size / Ada.Streams.Stream_Element'Size

1.4/2           The value of this attribute is of type universal_integer and
                is a multiple of Stream_Element'Size.

1.5/2           Stream_Size may be specified for first subtypes via an
                attribute_definition_clause; the expression of such a clause
                shall be static, nonnegative, and a multiple of
                Stream_Element'Size.

1.a/3       Aspect Description for Stream_Size: Size in bits used to represent
            elementary objects in a stream.

1.b/2       Discussion: Stream_Size is a type-related attribute (see 13.1).

1.c/3       Ramification: {AI05-0194-1} The value of S'Stream_Size is
            unaffected by the presence or absence of any
            attribute_definition_clauses or aspect_specifications specifying
            the Read or Write attributes of any ancestor of S. S'Stream_Size
            is defined in terms of the behavior of the default implementations
            of S'Read and S'Write even if those default implementations are
            overridden.


                            Implementation Advice

1.6/2 {AI95-00270-01} If not specified, the value of Stream_Size for an
elementary type should be the number of bits that corresponds to the minimum
number of stream elements required by the first subtype of the type, rounded
up to the nearest factor or multiple of the word size that is also a multiple
of the stream element size.

1.d/2       Implementation Advice: If not specified, the value of Stream_Size
            for an elementary type should be the number of bits that
            corresponds to the minimum number of stream elements required by
            the first subtype of the type, rounded up to the nearest factor or
            multiple of the word size that is also a multiple of the stream
            element size.

1.e/2       Reason: {AI95-00270-01} This is Implementation Advice because we
            want to allow implementations to remain compatible with their Ada
            95 implementations, which may have a different handling of the
            number of stream elements. Users can always specify Stream_Size if
            they need a specific number of stream elements.

1.7/2 {AI95-00270-01} The recommended level of support for the Stream_Size
attribute is:

1.8/2   * {AI95-00270-01} A Stream_Size clause should be supported for a
        discrete or fixed point type T if the specified Stream_Size is a
        multiple of Stream_Element'Size and is no less than the size of the
        first subtype of T, and no greater than the size of the largest type
        of the same elementary class (signed integer, modular integer,
        enumeration, ordinary fixed point, or decimal fixed point).

1.f/2       Implementation Advice: The recommended level of support for the
            Stream_Size attribute should be followed.

1.g/2       Ramification: There are no requirements beyond supporting
            confirming Stream_Size clauses for floating point and access
            types. Floating point and access types usually only have a handful
            of defined formats, streaming anything else makes no sense for
            them.

1.h/2       For discrete and fixed point types, this may require support for
            sizes other than the "natural" ones. For instance, on a typical
            machine with 32-bit integers and a Stream_Element'Size of 8,
            setting Stream_Size to 24 must be supported. This is required as
            such formats can be useful for interoperability with unusual
            machines, and there is no difficulty with the implementation (drop
            extra bits on output, sign extend on input).


                              Static Semantics

2   For every subtype S of a specific type T, the following attributes are
defined.

3   S'Write     S'Write denotes a procedure with the following specification:

4/2                 {AI95-00441-01} procedure S'Write(
                       Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                       Item : in T)

5               S'Write writes the value of Item to Stream.

6   S'Read      S'Read denotes a procedure with the following specification:

7/2                 {AI95-00441-01} procedure S'Read(
                       Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                       Item : out T)

8               S'Read reads the value of Item from Stream.

8.1/3 {8652/0040} {AI95-00108-01} {AI95-00444-01} {AI05-0192-1} For an
untagged derived type, the Write (resp. Read) attribute is inherited according
to the rules given in 13.1 if the attribute is [specified and] available for
the parent type at the point where T is declared. For a tagged derived type,
these attributes are not inherited, but rather the default implementations are
used.

8.a.1/3     Proof: {AI05-0192-1} The inheritance rules of 13.1 say that only
            specified or inherited aspects are inherited; we mention it again
            here as a clarification.

8.2/2 {AI95-00444-01} The default implementations of the Write and Read
attributes, where available, execute as follows:

9/3 {8652/0040} {AI95-00108-01} {AI95-00195-01} {AI95-00251-01}
{AI95-00270-01} {AI05-0139-2} For elementary types, Read reads (and Write
writes) the number of stream elements implied by the Stream_Size for the type
T; the representation of those stream elements is implementation defined. For
composite types, the Write or Read attribute for each component is called in
canonical order, which is last dimension varying fastest for an array (unless
the convention of the array is Fortran, in which case it is first dimension
varying fastest), and positional aggregate order for a record. Bounds are not
included in the stream if T is an array type. If T is a discriminated type,
discriminants are included only if they have defaults. If T is a tagged type,
the tag is not included. For type extensions, the Write or Read attribute for
the parent type is called, followed by the Write or Read attribute of each
component of the extension part, in canonical order. For a limited type
extension, if the attribute of the parent type or any progenitor type of T is
available anywhere within the immediate scope of T, and the attribute of the
parent type or the type of any of the extension components is not available at
the freezing point of T, then the attribute of T shall be directly specified.

9.a/2       Implementation defined: The contents of the stream elements read
            and written by the Read and Write attributes of elementary types.

9.1/3 {AI05-0023-1} {AI05-0264-1} If T is a discriminated type and its
discriminants have defaults, then S'Read first reads the discriminants from
the stream without modifying Item. S'Read then creates an object of type T
constrained by these discriminants. The value of this object is then converted
to the subtype of Item and is assigned to Item. Finally, the Read attribute
for each nondiscriminant component of Item is called in canonical order as
described above. Normal default initialization and finalization take place for
the created object.

9.b         Reason: A discriminant with a default value is treated simply as a
            component of the object. On the other hand, an array bound or a
            discriminant without a default value, is treated as "
            descriptor" or "dope" that must be provided in order to create the object
            and thus is logically separate from the regular components. Such
            "descriptor" data are written by 'Output and produced as part of
            the delivered result by the 'Input function, but they are not
            written by 'Write nor read by 'Read. A tag is like a discriminant
            without a default.

9.b.1/1     {8652/0040} {AI95-00108-01} For limited type extensions, we must
            have a definition of 'Read and 'Write if the parent type has one,
            as it is possible to make a dispatching call through the
            attributes. The rule is designed to automatically do the right
            thing in as many cases as possible.

9.b.2/1     {AI95-00251-01} Similarly, a type that has a progenitor with an
            available attribute must also have that attribute, for the same
            reason.

9.b.3/3     {AI05-0023-1} The semantics of S'Read for a discriminated type
            with defaults involves an anonymous object so that the point of
            required initialization and finalization is well-defined,
            especially for objects that change shape and have controlled
            components. The creation of this anonymous object often can be
            omitted (see the Implementation Permissions below).

9.c/2       Ramification: {AI95-00195-01} For a composite object, the
            subprogram denoted by the Write or Read attribute of each
            component is called, whether it is the default or is
            user-specified. Implementations are allowed to optimize these
            calls (see below), presuming the properties of the attributes are
            preserved.

9.2/3 {AI95-00270-01} {AI05-0264-1} Constraint_Error is raised by the
predefined Write attribute if the value of the elementary item is outside the
range of values representable using Stream_Size bits. For a signed integer
type, an enumeration type, or a fixed point type, the range is unsigned only
if the integer code for the lower bound of the first subtype is nonnegative,
and a (symmetric) signed range that covers all values of the first subtype
would require more than Stream_Size bits; otherwise, the range is signed.

10  For every subtype S'Class of a class-wide type T'Class:

11  S'Class'Write
                S'Class'Write denotes a procedure with the following
                specification:

12/2                {AI95-00441-01} procedure S'Class'Write(
                       Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                       Item   : in T'Class)

13              Dispatches to the subprogram denoted by the Write attribute of
                the specific type identified by the tag of Item.

14  S'Class'Read
                S'Class'Read denotes a procedure with the following
                specification:

15/2                {AI95-00441-01} procedure S'Class'Read(
                       Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                       Item : out T'Class)

16              Dispatches to the subprogram denoted by the Read attribute of
                the specific type identified by the tag of Item.

16.a        Reason: It is necessary to have class-wide versions of Read and
            Write in order to avoid generic contract model violations; in a
            generic, we don't necessarily know at compile time whether a given
            type is specific or class-wide.

Paragraph 17 was deleted.


                              Static Semantics

18  For every subtype S of a specific type T, the following attributes are
defined.

19  S'Output    S'Output denotes a procedure with the following specification:

20/2                {AI95-00441-01} procedure S'Output(
                       Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                       Item : in T)

21              S'Output writes the value of Item to Stream, including any
                bounds or discriminants.

21.a        Ramification: Note that the bounds are included even for an array
            type whose first subtype is constrained.

22  S'Input     S'Input denotes a function with the following specification:

23/2                {AI95-00441-01} function S'Input(
                       Stream : not null access Ada.Streams.Root_Stream_Type'Class)
                       return T

24              S'Input reads and returns one value from Stream, using any
                bounds or discriminants written by a corresponding S'Output to
                determine how much to read.

25/3 {8652/0040} {AI95-00108-01} {AI95-00444-01} {AI05-0192-1} For an untagged
derived type, the Output (resp. Input) attribute is inherited according to the
rules given in 13.1 if the attribute is [specified and] available for the
parent type at the point where T is declared. For a tagged derived type, these
attributes are not inherited, but rather the default implementations are used.

25.a/3      Proof: {AI05-0192-1} See the note following the inheritance rules
            for the Write attribute, above.

25.1/2 {AI95-00444-01} The default implementations of the Output and Input
attributes, where available, execute as follows:

26/3   * {AI05-0269-1} If T is an array type, S'Output first writes the
        bounds, and S'Input first reads the bounds. If T has discriminants
        without defaults, S'Output first writes the discriminants (using the
        Write attribute of the discriminant type for each), and S'Input first
        reads the discriminants (using the Read attribute of the discriminant
        type for each).

27/3   * {AI95-00195-01} {AI05-0023-1} S'Output then calls S'Write to write
        the value of Item to the stream. S'Input then creates an object of
        type T, with the bounds or (when without defaults) the discriminants,
        if any, taken from the stream, passes it to S'Read, and returns the
        value of the object. If T has discriminants, then this object is
        unconstrained if and only the discriminants have defaults. Normal
        default initialization and finalization take place for this object
        (see 3.3.1, 7.6, and 7.6.1).

27.1/2 {AI95-00251-01} If T is an abstract type, then S'Input is an abstract
function.

27.a/2      Ramification: For an abstract type T, S'Input can be called in a
            dispatching call, or passed to an abstract formal subprogram. But
            it cannot be used in nondispatching contexts, because we don't
            allow objects of abstract types to exist. The designation of this
            function as abstract has no impact on descendants of T, as T'Input
            is not inherited for tagged types, but rather recreated (and the
            default implementation of T'Input calls T'Read, not the parent
            type's T'Input). Note that T'Input cannot be specified in this
            case, as any function with the proper profile is necessarily
            abstract, and specifying abstract subprograms in an
            attribute_definition_clause is illegal.

28  For every subtype S'Class of a class-wide type T'Class:

29  S'Class'Output
                S'Class'Output denotes a procedure with the following
                specification:

30/2                {AI95-00441-01} procedure S'Class'Output(
                       Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                       Item   : in T'Class)

31/2            {AI95-00344-01} First writes the external tag of Item to
                Stream (by calling String'Output(Stream,
                Tags.External_Tag(Item'Tag)) - see 3.9) and then dispatches to
                the subprogram denoted by the Output attribute of the specific
                type identified by the tag. Tag_Error is raised if the tag of
                Item identifies a type declared at an accessibility level
                deeper than that of S.

31.a/2      Reason: {AI95-00344-01} We raise Tag_Error here for nested types
            as such a type cannot be successfully read with S'Class'Input, and
            it doesn't make sense to allow writing a value that cannot be
            read.

32  S'Class'Input
                S'Class'Input denotes a function with the following
                specification:

33/2                {AI95-00441-01} function S'Class'Input(
                       Stream : not null access Ada.Streams.Root_Stream_Type'Class)
                       return T'Class

34/3            {AI95-00279-01} {AI95-00344-01} {AI05-0109-1} First reads the
                external tag from Stream and determines the corresponding
                internal tag (by calling
                Tags.Descendant_Tag(String'Input(Stream), S'Tag) which might
                raise Tag_Error - see 3.9) and then dispatches to the
                subprogram denoted by the Input attribute of the specific type
                identified by the internal tag; returns that result. If the
                specific type identified by the internal tag is abstract,
                Constraint_Error is raised.

34.a/3      Ramification: {AI05-0109-1} Descendant_Tag will ensure that the
            tag it returns is covered by T'Class; Tag_Error will be raised if
            it would not cover T'Class.

35/3 {AI95-00195-01} {AI05-0228-1} In the default implementation of Read and
Input for a composite type, for each scalar component that is a discriminant
or that has an implicit initial value, a check is made that the value returned
by Read for the component belongs to its subtype. Constraint_Error is raised
if this check fails. For other scalar components, no check is made. For each
component that is of an access type, if the implementation can detect that the
value returned by Read for the component is not a value of its subtype,
Constraint_Error is raised. If the value is not a value of its subtype and
this error is not detected, the component has an abnormal value, and erroneous
execution can result (see 13.9.1). In the default implementation of Read for a
composite type with defaulted discriminants, if the actual parameter of Read
is constrained, a check is made that the discriminants read from the stream
are equal to those of the actual parameter. Constraint_Error is raised if this
check fails.

35.a/3      Reason: {AI05-0228-1} The check for scalar components that have an
            implicit initial value is to preserve our
            Language Design Principle that all objects that have an implicit
            initial value do not become "deinitialized".

35.b/3      Ramification: {AI05-0228-1} A scalar component can have an
            implicit initial value if it has a default_expression, if the
            component's type has the Default_Value aspect specified, or if the
            component is that of an array type that has the
            Default_Component_Value aspect specified.

35.c/3      To be honest: {AI05-0228-1} An implementation should always be
            able to detect the error for a null value read into a component of
            an access subtype with a null exclusion; the "if the
            implementation can detect" is intended to cover nonnull access
            values.

36/2 {AI95-00195-01} It is unspecified at which point and in which order these
checks are performed. In particular, if Constraint_Error is raised due to the
failure of one of these checks, it is unspecified how many stream elements
have been read from the stream.

37/1 {8652/0045} {AI95-00132-01} In the default implementation of Read and
Input for a type, End_Error is raised if the end of the stream is reached
before the reading of a value of the type is completed.

38/4 {8652/0040} {AI95-00108-01} {AI95-00195-01} {AI95-00251-01}
{AI05-0039-1} {AI12-0106-1} {AI12-0121-1} The stream-oriented attributes may be
specified for any type via an attribute_definition_clause. [Alternatively,
each of the specific stream-oriented attributes may be specified using an
aspect_specification on any type_declaration, with the aspect name being the
corresponding attribute name.] Each of the class-wide stream-oriented
attributes may be specified using an aspect_specification for a tagged type T
using the name of the stream-oriented attribute followed by 'Class; such
class-wide aspects do not apply to other descendants of T.

38.a/4      Reason: {AI95-00195-01} {AI12-0106-1} We need the last sentence to
            override the blanket rule given in 13.1.1 that aspect'Class
            applies to the type and all descendants.

38.a.1/2    This paragraph was deleted.{8652/0040} {AI95-00108-01}
            {AI95-00195-01}

38.a.2/4    Proof: {AI12-0121-1} 13.1.1 says that all operational attributes
            can be specified with an aspect_specification.

38.a.3/4    Aspect Description for Read'Class: Procedure to read a value from
            a stream for the class-wide type associated with a given type.

38.a.4/4    Aspect Description for Write'Class: Procedure to write a value to
            a stream for a the class-wide type associated with a given type.

38.a.5/4    Aspect Description for Input'Class: Function to read a value from
            a stream for a the class-wide type associated with a given type,
            including any bounds and discriminants.

38.a.6/4    Aspect Description for Output'Class: Procedure to write a value to
            a stream for a the class-wide type associated with a given type,
            including any bounds and discriminants.

38.1/4 {AI12-0121-1} The subprogram name given in such an attribute_definition_-
clause or aspect_specification shall statically denote a subprogram that is
not an abstract subprogram. Furthermore, if a specific stream-oriented
attribute is specified for an interface type, the subprogram name given in the
attribute_definition_clause or aspect_specification shall statically denote a
null procedure.

38.b/2      Discussion: {AI95-00251-01} Stream attributes (other than Input)
            are always null procedures for interface types (they have no
            components). We need to allow explicit setting of the Read and
            Write attributes in order that the class-wide attributes like
            LI'Class'Input can be made available. (In that case, any
            descendant of the interface type would require available
            attributes.) But we don't allow any concrete implementation
            because these don't participate in extensions (unless the
            interface is the parent type). If we didn't ban concrete
            implementations, the order of declaration of a pair of interfaces
            would become significant. For example, if Int1 and Int2 are
            interfaces with concrete implementations of 'Read, then the
            following declarations would have different implementations for
            'Read:

38.c/2          type Con1 is new Int1 and Int2 with null record;
                type Con2 is new Int2 and Int1 with null record;

38.d/2      This would violate our design principle that the order of the
            specification of the interfaces in a derived_type_definition
            doesn't matter.

38.e/2      Ramification: The Input attribute cannot be specified for an
            interface. As it is a function, a null procedure is impossible; a
            concrete function is not possible anyway as any function returning
            an abstract type must be abstract. And we don't allow specifying
            stream attributes to be abstract subprograms. This has no impact,
            as the availability of Int'Class'Input (where Int is a limited
            interface) depends on whether Int'Read (not Int'Input) is
            specified. There is no reason to allow Int'Output to be specified,
            either, but there is equally no reason to disallow it, so we don't
            have a special rule for that.

38.f/2      Discussion: {AI95-00195-01} Limited types generally do not have
            default implementations of the stream-oriented attributes. The
            rules defining when a stream-oriented attribute is available (see
            below) determine when an attribute of a limited type is in fact
            well defined and usable. The rules are designed to maximize the
            number of cases in which the attributes are usable. For instance,
            when the language provides a default implementation of an
            attribute for a limited type based on a specified attribute for
            the parent type, we want to be able to call that attribute.

38.g/3      Aspect Description for Read: Procedure to read a value from a
            stream for a given type.

38.h/3      Aspect Description for Write: Procedure to write a value to a
            stream for a given type.

38.i/3      Aspect Description for Input: Function to read a value from a
            stream for a given type, including any bounds and discriminants.

38.j/3      Aspect Description for Output: Procedure to write a value to a
            stream for a given type, including any bounds and discriminants.

39/2 {AI95-00195-01} A stream-oriented attribute for a subtype of a specific
type T is available at places where one of the following conditions is true:

40/2   * T is nonlimited.

41/2   * The attribute_designator is Read (resp. Write) and T is a limited
        record extension, and the attribute Read (resp. Write) is available
        for the parent type of T and for the types of all of the extension
        components.

41.a/2      Reason: In this case, the language provides a well-defined default
            implementation, which we want to be able to call.

42/2   * T is a limited untagged derived type, and the attribute was inherited
        for the type.

42.a/2      Reason: Attributes are only inherited for untagged derived types,
            and surely we want to be able to call inherited attributes.

43/2   * The attribute_designator is Input (resp. Output), and T is a limited
        type, and the attribute Read (resp. Write) is available for T.

43.a/2      Reason: The default implementation of Input and Output are based
            on Read and Write; so if the implementation of Read or Write is
            good, so is the matching implementation of Input or Output.

44/2   * The attribute has been specified via an attribute_definition_clause,
        and the attribute_definition_clause is visible.

44.a/2      Reason: We always want to allow calling a specified attribute. But
            we don't want availability to break privacy. Therefore, only
            attributes whose specification can be seen count. Yes, we defined
            the visibility of an attribute_definition_clause (see 8.3).

45/2 {AI95-00195-01} A stream-oriented attribute for a subtype of a class-wide
type T'Class is available at places where one of the following conditions is
true:

46/2   * T is nonlimited;

47/2   * the attribute has been specified via an attribute_definition_clause,
        and the attribute_definition_clause is visible; or

48/2   * the corresponding attribute of T is available, provided that if T has
        a partial view, the corresponding attribute is available at the end of
        the visible part where T is declared.

48.a/2      Reason: The rules are stricter for class-wide attributes because
            (for the default implementation) we must ensure that any specific
            attribute that might ever be dispatched to is available. Because
            we require specification of attributes for extensions of limited
            parent types with available attributes, we can in fact know this.
            Otherwise, we would not be able to use default class-wide
            attributes with limited types, a significant limitation.

49/4 {AI95-00195-01} {AI12-0030-1} An attribute_reference for one of the
stream-oriented attributes is illegal unless the attribute is available at the
place of the attribute_reference. Furthermore, an attribute_reference for
T'Input is illegal if T is an abstract type. In addition to the places where
Legality Rules normally apply (see 12.3), these rules also apply in the
private part of an instance of a generic unit.

49.a/2      Discussion: Stream attributes always exist. It is illegal to call
            them in some cases. Having the attributes not be defined for some
            limited types would seem to be a cleaner solution, but it would
            lead to contract model problems for limited private types.

49.b/2      T'Input is available for abstract types so that T'Class'Input is
            available. But we certainly don't want to allow calls that could
            create an object of an abstract type. Remember that T'Class is
            never abstract, so the above legality rule doesn't apply to it. We
            don't have to discuss whether the attribute is specified, as it
            cannot be: any function returning the type would have to be
            abstract, and we do not allow specifying an attribute with an
            abstract subprogram.

49.c/4      To be honest: {AI12-0030-1} "These rules apply" refers to just
            this paragraph and not to the rest of the rules in this section.
            This rule probably should have been a Legality Rule, but the word
            "illegal" should key the reader that this is a Legality Rule, no
            matter under what text heading it occurs.

49.1/4 {AI12-0030-1} Unless inherited from a parent type, if any, for an
untagged type having a task, protected, or explicitly limited record part, the
default implementation of each of the Read, Write, Input, and Output
attributes raises Program_Error and performs no other action.

49.d/4      Discussion: {AI12-0030-1} It might seem that there is no need to
            specify the behavior of the default implementation of a streaming
            attribute of, for example, a task type because there is no way
            that it can be invoked. It is possible, however, to construct an
            example where such a stream attribute can be invoked. This
            involves using a formal untagged limited derived type for which
            some streaming attribute is available (because it was explicitly
            specified for the ancestor type) and a corresponding actual type
            for which the attribute is unspecified (because the derivation
            occurred before the aspect was specified for the ancestor type and
            the specification was therefore not inherited).

50/3 {AI95-00195-01} {AI05-0192-1} In the parameter_and_result_profiles for
the default implementations of the stream-oriented attributes, the subtype of
the Item parameter is the base subtype of T if T is a scalar type, and the
first subtype otherwise. The same rule applies to the result of the Input
attribute.

50.a/3      Discussion: {AI05-0192-1} An inherited stream attribute has a
            profile as determined by the rules for inheriting primitive
            subprograms (see 13.1 and 3.4).

51/3 {AI95-00195-01} {AI05-0007-1} For an attribute_definition_clause
specifying one of these attributes, the subtype of the Item parameter shall be
the first subtype or the base subtype if scalar, and the first subtype if not
scalar. The same rule applies to the result of the Input function.

51.a/2      Reason: This is to simplify implementation.

51.b/3      Ramification: The view of the type at the point of the
            attribute_definition_clause determines whether the base subtype is
            allowed. Thus, for a scalar type with a partial view (which is
            never scalar), whether the base subtype is allowed is determined
            by whether the attribute_definition_clause occurs before or after
            the full definition of the scalar type.

52/3 {AI95-00366-01} {AI05-0065-1} [A type is said to support external
streaming if Read and Write attributes are provided for sending values of such
a type between active partitions, with Write marshalling the representation,
and Read unmarshalling the representation.] A limited type supports external
streaming only if it has available Read and Write attributes. A type with a
part that is of a nonremote access type supports external streaming only if
that access type or the type of some part that includes the access type
component, has Read and Write attributes that have been specified via an
attribute_definition_clause, and that attribute_definition_clause is visible.
[An anonymous access type does not support external streaming. ]All other
types (including remote access types, see E.2.2) support external streaming.

52.a/3      Ramification: A limited type with a part that is of a nonremote
            access type needs to satisfy both rules.


                             Erroneous Execution

53/2 {AI95-00279-01} {AI95-00344-01} If the internal tag returned by
Descendant_Tag to T'Class'Input identifies a type that is not library-level
and whose tag has not been created, or does not exist in the partition at the
time of the call, execution is erroneous.

53.a/2      Ramification: The definition of Descendant_Tag prevents such a tag
            from being provided to T'Class'Input if T is a library-level type.
            However, this rule is needed for nested tagged types.


                         Implementation Requirements

54/1 {8652/0040} {AI95-00108-01} For every subtype S of a language-defined
nonlimited specific type T, the output generated by S'Output or S'Write shall
be readable by S'Input or S'Read, respectively. This rule applies across
partitions if the implementation conforms to the Distributed Systems Annex.

55/3 {AI95-00195-01} {AI05-0092-1} If Constraint_Error is raised during a call
to Read because of failure of one the above checks, the implementation shall
ensure that the discriminants of the actual parameter of Read are not
modified.


                         Implementation Permissions

56/3 {AI95-00195-01} {AI05-0092-1} The number of calls performed by the
predefined implementation of the stream-oriented attributes on the Read and
Write operations of the stream type is unspecified. An implementation may take
advantage of this permission to perform internal buffering. However, all the
calls on the Read and Write operations of the stream type needed to implement
an explicit invocation of a stream-oriented attribute shall take place before
this invocation returns. An explicit invocation is one appearing explicitly in
the program text, possibly through a generic instantiation (see 12.3).

56.1/3 {AI05-0023-1} {AI05-0264-1} If T is a discriminated type and its
discriminants have defaults, then in two cases an execution of the default
implementation of S'Read is not required to create an anonymous object of type
T: If the discriminant values that are read in are equal to the corresponding
discriminant values of Item, then no object of type T need be created and Item
may be used instead. If they are not equal and Item is a constrained variable,
then Constraint_Error may be raised at that point, before any further values
are read from the stream and before the object of type T is created.

56.2/3 {AI05-0023-1} A default implementation of S'Input that calls the
default implementation of S'Read may create a constrained anonymous object
with discriminants that match those in the stream.

56.a/3      Implementation Note: This allows the combined executions of
            S'Input and S'Read to create one object of type T instead of two.
            If this option is exercised, then:

56.b/3        * The discriminants are read from the stream by S'Input, not
                S'Read.

56.c/3        * S'Input declares an object of type T constrained by the
                discriminants read from the stream, not an unconstrained
                object.

56.d/3        * The discriminant values that S'Read would normally have read
                from the stream are read from Item instead.

56.e/3        * The permissions of the preceding paragraph then apply and no
                object of type T need be created by the execution of S'Read.

        NOTES

57      40  For a definite subtype S of a type T, only T'Write and T'Read are
        needed to pass an arbitrary value of the subtype through a stream. For
        an indefinite subtype S of a type T, T'Output and T'Input will
        normally be needed, since T'Write and T'Read do not pass bounds,
        discriminants, or tags.

58      41  User-specified attributes of S'Class are not inherited by other
        class-wide types descended from S.


                                  Examples

59  Example of user-defined Write attribute:

60/2    {AI95-00441-01} procedure My_Write(
          Stream : not null access Ada.Streams.Root_Stream_Type'Class;
          Item   : My_Integer'Base);
        for My_Integer'Write use My_Write;

60.a        Discussion: Example of network input/output using input output
            attributes:

60.b            with Ada.Streams; use Ada.Streams;
                generic
                    type Msg_Type(<>) is private;
                package Network_IO is
                    -- Connect/Disconnect are used to establish the stream
                    procedure Connect(...);
                    procedure Disconnect(...);

60.c                -- Send/Receive transfer messages across the network
                    procedure Send(X : in Msg_Type);
                    function Receive return Msg_Type;
                private
                    type Network_Stream is new Root_Stream_Type with ...
                    procedure Read(...);  -- define Read/Write for Network_Stream
                    procedure Write(...);
                end Network_IO;

60.d            with Ada.Streams; use Ada.Streams;
                package body Network_IO is
                    Current_Stream : aliased Network_Stream;
                    . . .
                    procedure Connect(...) is ...;
                    procedure Disconnect(...) is ...;

60.e                procedure Send(X : in Msg_Type) is
                    begin
                        Msg_Type'Output(Current_Stream'Access, X);
                    end Send;

60.f                function Receive return Msg_Type is
                    begin
                        return Msg_Type'Input(Current_Stream'Access);
                    end Receive;
                end Network_IO;


                         Inconsistencies With Ada 95

60.g/2      {8652/0040} {AI95-00108-01} Corrigendum: Clarified how the default
            implementation for stream attributes is determined (eliminating
            conflicting language). The new wording provides that attributes
            for type extensions are created by composing the parent's
            attribute with those for the extension components if any. If a
            program was written assuming that the extension components were
            not included in the stream (as in original Ada 95), it would fail
            to work in the language as corrected by the Corrigendum.

60.h/2      {AI95-00195-01} Amendment Correction: Explicitly provided a
            permission that the number of calls to the underlying stream Read
            and Write operations may differ from the number determined by the
            canonical operations. If Ada 95 code somehow depended on the
            number of calls to Read or Write, it could fail with an Ada 2005
            implementation. Such code is likely to be very rare; moreover,
            such code is really wrong, as the permission applies to Ada 95 as
            well.


                            Extensions to Ada 95

60.i/2      {AI95-00270-01} The Stream_Size attribute is new. It allows
            specifying the number of bits that will be streamed for a type.
            The Implementation Advice involving this also was changed; this is
            not incompatible because Implementation Advice does not have to be
            followed.

60.j/2      {8652/0040} {AI95-00108-01} {AI95-00195-01} {AI95-00444-01}
            Corrigendum: Limited types may have default constructed attributes
            if all of the parent and (for extensions) extension components
            have available attributes. Ada 2005 adds the notion of
            availability to patch up some holes in the Corrigendum model.


                         Wording Changes from Ada 95

60.k/2      {8652/0009} {AI95-00137-01} Corrigendum: Added wording to specify
            that these are operational attributes.

60.l/2      {8652/0045} {AI95-00132-01} Corrigendum: Clarified that End_Error
            is raised by the default implementation of Read and Input if the
            end of the stream is reached. (The result could have been abnormal
            without this clarification, thus this is not an inconsistency, as
            the programmer could not have depended on the previous behavior.)

60.m/2      {AI95-00195-01} Clarified that the default implementation of
            S'Input does normal initialization on the object that it passes to
            S'Read.

60.n/2      {AI95-00195-01} Explicitly stated that what is read from a stream
            when a required check fails is unspecified.

60.o/2      {AI95-00251-01} Defined availability and default implementations
            for types with progenitors.

60.p/2      {AI95-00279-01} Specified that Constraint_Error is raised if the
            internal tag retrieved for S'Class'Input is for some type not
            covered by S'Class or is abstract. We also explicitly state that
            the program is erroneous if the tag has not been created or does
            not currently exist in the partition. (Ada 95 did not specify what
            happened in these cases; it's very unlikely to have provided some
            useful result, so this is not considered an inconsistency.)

60.q/2      {AI95-00344-01} Added wording to support nested type extensions.
            S'Input and S'Output always raise Tag_Error for such extensions,
            and such extensions were not permitted in Ada 95, so this is
            neither an extension nor an incompatibility.

60.r/2      {AI95-00366-01} Defined supports external streaming to put all of
            the rules about "good" stream attributes in one place. This is
            used for distribution and for defining pragma Pure.

60.s/2      {AI95-00441-01} Added the not null qualifier to the first
            parameter of all of the stream attributes, so that the semantics
            doesn't change between Ada 95 and Ada 2005. This change is
            compatible, because mode conformance is required for subprograms
            specified as stream attributes, and null_exclusions are not
            considered for mode conformance.

60.t/2      {AI95-00444-01} Improved the wording to make it clear that we
            don't define the default implementations of attributes that cannot
            be called (that is, aren't "available"). Also clarified when
            inheritance takes place.


                       Incompatibilities With Ada 2005

60.u/3      {AI05-0039-1} Correction: Added a requirement that stream
            attributes be specified by a static subprogram name rather than a
            dynamic expression. Expressions cannot provide any useful
            functionality because of the freezing rules, and the possibility
            of them complicates implementations. Only pathological programs
            should be affected.


                           Extensions to Ada 2005

60.v/3      {AI05-0007-1} Correction: Stream attributes for scalar types can
            be specified with subprograms that take the first subtype as well
            as the base type. This eliminates confusion about which subtype is
            appropriate for attributes specified for partial views whose full
            type is a scalar type. It also eliminates a common user error
            (forgetting 'Base).


                        Wording Changes from Ada 2005

60.w/3      {AI05-0023-1} Correction: Corrected the definition of the default
            version S'Read and S'Input to be well-defined if S is a
            discriminated type with defaulted discriminants and some
            components require initialization and/or finalizations.

60.x/3      {AI05-0065-1} Correction: Defined remote access types to support
            external streaming, since that is their purpose.

60.y/3      {AI05-0109-1} Correction: Removed a misleading phrase which
            implies that Constraint_Error is raised for internal tags of the
            wrong type, when Tag_Error should be raised for such tags.

60.z/3      {AI05-0139-2} Clarified that arrays with convention Fortran are
            written in column-major order, rather then row-major order. This
            is necessary in order that streaming of Fortran arrays is
            efficient.

60.aa/3     {AI05-0192-1} Correction: Clarified that the profile of an
            inherited stream attribute is as defined for an inherited
            primitive subprogram, while the default implementation of the same
            attribute might have a different profile.

60.bb/3     {AI05-0194-1} Correction: Clarified that Stream_Size has no effect
            on and is not effected by user-defined stream attributes.


                           Extensions to Ada 2012

60.cc/4     {AI12-0106-1} Corrigendum: Defined how to specify a class-wide
            stream-oriented attribute using an aspect_specification. It was
            always intended that this was possible, but the method was not
            clear, as a class-wide type never has an explicit declaration.


                        Wording Changes from Ada 2012

60.dd/4     {AI12-0030-1} Corrigendum: Defined the runtime effect of stream
            attributes for untagged limited types, as there is a weird corner
            case where they can be called. We don't specify this as an
            inconsistency, as it doesn't make semantic sense to stream a task,
            and nothing useful could have been done with that, so it should
            not exist in any programs.

60.ee/4     {AI12-0106-1} Corrigendum: Clarified that the same
            Legality Rules apply when a stream-oriented attribute is specified
            via an aspect_specification as applied when it is specified via an
            attribute_definition_clause.


13.14 Freezing Rules


1/3 {AI05-0299-1} [This subclause defines a place in the program text where
each declared entity becomes "frozen." A use of an entity, such as a reference
to it by name, or (for a type) an expression of the type, causes freezing of
the entity in some contexts, as described below. The Legality Rules forbid
certain kinds of uses of an entity in the region of text where it is frozen.]

1.a         Reason: This concept has two purposes: a compile-time one and a
            run-time one.

1.b         The compile-time purpose of the freezing rules comes from the fact
            that the evaluation of static expressions depends on overload
            resolution, and overload resolution sometimes depends on the value
            of a static expression. (The dependence of static evaluation upon
            overload resolution is obvious. The dependence in the other
            direction is more subtle. There are three rules that require
            static expressions in contexts that can appear in declarative
            places: The expression in an attribute_designator shall be static.
            In a record aggregate, variant-controlling discriminants shall be
            static. In an array aggregate with more than one named
            association, the choices shall be static. The compiler needs to
            know the value of these expressions in order to perform overload
            resolution and legality checking.) We wish to allow a compiler to
            evaluate static expressions when it sees them in a single pass
            over the compilation_unit. The freezing rules ensure that.

1.c         The run-time purpose of the freezing rules is called the "linear
            elaboration model." This means that declarations are elaborated in
            the order in which they appear in the program text, and later
            elaborations can depend on the results of earlier ones. The
            elaboration of the declarations of certain entities requires
            run-time information about the implementation details of other
            entities. The freezing rules ensure that this information has been
            calculated by the time it is used. For example, suppose the
            initial value of a constant is the result of a function call that
            takes a parameter of type T. In order to pass that parameter, the
            size of type T has to be known. If T is composite, that size might
            be known only at run time.

1.d         (Note that in these discussions, words like "before" and "
            after" generally refer to places in the program text, as opposed to
            times at run time.)

1.e         Discussion: The "implementation details" we're talking about above
            are:

1.f           * For a tagged type, the implementations of all the primitive
                subprograms of the type - that is (in the canonical
                implementation model), the contents of the type descriptor,
                which contains pointers to the code for each primitive
                subprogram.

1.g           * For a type, the full type declaration of any parts (including
                the type itself) that are private.

1.h           * For a deferred constant, the full constant declaration, which
                gives the constant's value. (Since this information
                necessarily comes after the constant's type and subtype are
                fully known, there's no need to worry about its type or
                subtype.)

1.i           * For any entity, representation information specified by the
                user via representation items. Most representation items are
                for types or subtypes; however, various other kinds of
                entities, such as objects and subprograms, are possible.

1.j/3       {AI05-0005-1} Similar issues arise for incomplete types. However,
            we do not use freezing to prevent premature access; incomplete
            types have different, more severe, restrictions. Similar issues
            also arise for subprograms, protected operations, tasks and
            generic units. However, we do not use freezing to prevent
            premature access for those, either; 3.11 prevents problems with
            run-time Elaboration_Checks. Even so, freezing is used for these
            entities to prevent giving representation items too late (that is,
            after uses that require representation information, such as
            calls).


                         Language Design Principles

1.k         An evaluable construct should freeze anything that's needed to
            evaluate it.

1.l         However, if the construct is not evaluated where it appears, let
            it cause freezing later, when it is evaluated. This is the case
            for default_expressions and default_names. (Formal parameters,
            generic formal parameters, and components can have
            default_expressions or default_names.)

1.m         The compiler should be allowed to evaluate static expressions
            without knowledge of their context. (I.e. there should not be any
            special rules for static expressions that happen to occur in a
            context that requires a static expression.)

1.n         Compilers should be allowed to evaluate static expressions (and
            record the results) using the run-time representation of the type.
            For example, suppose Color'Pos(Red) = 1, but the internal code for
            Red is 37. If the value of a static expression is Red, some
            compilers might store 1 in their symbol table, and other compilers
            might store 37. Either compiler design should be feasible.

1.o         Compilers should never be required to detect erroneousness or
            exceptions at compile time (although it's very nice if they do).
            This implies that we should not require code-generation for a
            nonstatic expression of type T too early, even if we can prove
            that that expression will be erroneous, or will raise an exception.

1.p         Here's an example (modified from AI83-00039, Example 3):

1.q             type T is
                    record
                        ...
                    end record;
                function F return T;
                function G(X : T) return Boolean;
                Y : Boolean := G(F); -- doesn't force T in Ada 83
                for T use
                    record
                        ...
                    end record;

1.r         AI83-00039 says this is legal. Of course, it raises Program_Error
            because the function bodies aren't elaborated yet. A one-pass
            compiler has to generate code for an expression of type T before
            it knows the representation of T. Here's a similar example, which
            AI83-00039 also says is legal:

1.s             package P is
                    type T is private;
                    function F return T;
                    function G(X : T) return Boolean;
                    Y : Boolean := G(F); -- doesn't force T in Ada 83
                private
                    type T is
                        record
                            ...
                        end record;
                end P;

1.t         If T's size were dynamic, that size would be stored in some
            compiler-generated dope; this dope would be initialized at the
            place of the full type declaration. However, the generated code
            for the function calls would most likely allocate a temp of the
            size specified by the dope before checking for Program_Error. That
            dope would contain uninitialized junk, resulting in disaster. To
            avoid doing that, the compiler would have to determine, at compile
            time, that the expression will raise Program_Error.

1.u         This is silly. If we're going to require compilers to detect the
            exception at compile time, we might as well formulate the rule as
            a legality rule.

1.v         Compilers should not be required to generate code to load the
            value of a variable before the address of the variable has been
            determined.

1.w         After an entity has been frozen, no further requirements may be
            placed on its representation (such as by a representation item or
            a full_type_declaration).

2   The freezing of an entity occurs at one or more places (freezing points)
in the program text where the representation for the entity has to be fully
determined. Each entity is frozen from its first freezing point to the end of
the program text (given the ordering of compilation units defined in 10.1.4).

2.a         Ramification: The "representation" for a subprogram includes its
            calling convention and means for referencing the subprogram body,
            either a "link-name" or specified address. It does not include the
            code for the subprogram body itself, nor its address if a
            link-name is used to reference the body.

2.1/3 {AI05-0019-1} {AI05-0299-1} This subclause also defines a place in the
program text where the profile of each declared callable entity becomes
frozen. A use of a callable entity causes freezing of its profile in some
contexts, as described below. At the place where the profile of a callable
entity becomes frozen, the entity itself becomes frozen.

3/4 {8652/0014} {AI05-0017-1} {AI05-0019-1} {AI12-0103-1} The end of a
declarative_part, protected_body, or a declaration of a library package or
generic library package, causes freezing of each entity and profile declared
within it, except for incomplete types. A proper_body, body_stub, or
entry_body causes freezing of each entity and profile declared before it
within the same declarative_part that is not an incomplete type; it only
causes freezing of an incomplete type if the body is within the immediate
scope of the incomplete type.

3.a         Discussion: This is worded carefully to handle nested packages and
            private types. Entities declared in a nested
            package_specification will be frozen by some containing construct.

3.b/3       {AI05-0017-1} An incomplete type declared in the private part of a
            library package_specification can be completed in the body. For
            other incomplete types (and in the bodies of library packages),
            the completion of the type will be frozen at the end of the
            package or declarative_part, and that will freeze the incomplete
            view as well.

3.b.1/3     {AI05-0017-1} The reason we have to worry about freezing of
            incomplete types is to prevent premature uses of the types in
            dispatching calls. Such uses may need access to the tag of the
            type, and the type has to be frozen to know where the tag is
            stored.

3.c/3       Ramification: {AI05-0229-1} The part about bodies does not say
            immediately within. A renaming-as-body does not have this
            property. Nor does an imported body

3.d         Reason: The reason bodies cause freezing is because we want
            proper_bodies and body_stubs to be interchangeable - one should be
            able to move a proper_body to a subunit, and vice-versa, without
            changing the semantics. Clearly, anything that should cause
            freezing should do so even if it's inside a proper_body. However,
            if we make it a body_stub, then the compiler can't see that thing
            that should cause freezing. So we make body_stubs cause freezing,
            just in case they contain something that should cause freezing.
            But that means we need to do the same for proper_bodies.

3.e         Another reason for bodies to cause freezing, there could be an
            added implementation burden if an entity declared in an enclosing
            declarative_part is frozen within a nested body, since some
            compilers look at bodies after looking at the containing
            declarative_part.

3.f/4       {AI05-0177-1} {AI12-0103-1} Note that null_procedure_declarations
            and expression_function_declarations (even when those are used as
            completions), as well as generic_instantiations and
            renames-as-bodies do not necessarily cause freezing; each have
            their own specific rules.

3.g/4       Ramification: {AI12-0103-1} Note that the rule about proper bodies
            being freezing only applies in declarative_parts. All of the kinds
            of bodies (see 3.11.1 - keep in mind the difference from bodys)
            that are allowed in a package specification have their own
            freezing rules, so they don't need to be covered by the above
            rule.

4/1 {8652/0046} {AI95-00106-01} A construct that (explicitly or implicitly)
references an entity can cause the freezing of the entity, as defined by
subsequent paragraphs. At the place where a construct causes freezing, each
name, expression, implicit_dereference[, or range] within the construct causes
freezing:

4.a         Ramification: Note that in the sense of this paragraph, a
            subtype_mark "references" the denoted subtype, but not the type.

5/3   * {AI05-0213-1} The occurrence of a generic_instantiation causes
        freezing, except that a name which is a generic actual parameter whose
        corresponding generic formal parameter is a formal incomplete type
        (see 12.5.1) does not cause freezing. In addition, if a parameter of
        the instantiation is defaulted, the default_expression or
        default_name for that parameter causes freezing.

5.a/3       Ramification: {AI05-0213-1} Thus, an actual parameter
            corresponding to a formal incomplete type parameter may denote an
            incomplete or private type which is not completely defined at the
            point of the generic_instantiation.

5.1/4   * {AI12-0103-1} {AI12-0157-1} At the occurrence of an
        expression_function_declaration that is a completion, the return
        expression of the expression function causes freezing.

5.b/4       Reason: {AI12-0103-1} This rule prevents calls through access
            values to an expression that might have unfrozen parts. Typically,
            elaboration checks and other freezing rules prevent this, but in
            this case the completion is elaborated and since this is not a
            body it does not by itself freeze anything that precedes it.

5.2/4   * {AI12-0132-1} {AI12-0157-1} At the occurrence of a renames-as-body
        whose callable_entity_name denotes an expression function, the return
        expression of the expression function causes freezing.

6     * The occurrence of an object_declaration that has no corresponding
        completion causes freezing.

6.a         Ramification: Note that this does not include a
            formal_object_declaration.

7     * The declaration of a record extension causes freezing of the parent
        subtype.

7.a         Ramification: This combined with another rule specifying that
            primitive subprogram declarations shall precede freezing ensures
            that all descendants of a tagged type implement all of its
            dispatching operations.

7.b/2       {AI95-00251-01} The declaration of a private extension does not
            cause freezing. The freezing is deferred until the full type
            declaration, which will necessarily be for a record extension,
            task, or protected type (the latter only for a limited private
            extension derived from an interface).

7.1/2   * {AI95-00251-01} The declaration of a record extension, interface
        type, task unit, or protected unit causes freezing of any progenitor
        types specified in the declaration.

7.b.1/2     Reason: This rule has the same purpose as the one above: ensuring
            that all descendants of an interface tagged type implement all of
            its dispatching operations. As with the previous rule, a private
            extension does not freeze its progenitors; the full type
            declaration (which must have the same progenitors) will do that.

7.b.2/2     Ramification: An interface type can be a parent as well as a
            progenitor; these rules are similar so that the location of an
            interface in a record extension does not have an effect on the
            freezing of the interface type.

7.2/3   * {AI05-0183-1} At the freezing point of the entity associated with an
        aspect_specification, any expressions or names within the
        aspect_specification cause freezing. Any static expressions within an
        aspect_specification also cause freezing at the end of the immediately
        enclosing declaration list.

8/4 {8652/0046} {AI95-00106-01} {AI05-0177-1} {AI05-0183-1} {AI05-0157-1} A
static expression (other than within an aspect_specification) causes freezing
where it occurs. An object name or nonstatic expression causes freezing where
it occurs, unless the name or expression is part of a default_expression, a
default_name, the return expression of an expression function, an
aspect_specification, or a per-object expression of a component's constraint,
in which case, the freezing occurs later as part of another construct or at
the freezing point of an associated entity.

8.1/3 {8652/0046} {AI95-00106-01} {AI05-0019-1} An implicit call freezes the
same entities and profiles that would be frozen by an explicit call. This is
true even if the implicit call is removed via implementation permissions.

8.2/1 {8652/0046} {AI95-00106-01} If an expression is implicitly converted to
a type or subtype T, then at the place where the expression causes freezing, T
is frozen.

9   The following rules define which entities are frozen at the place where a
construct causes freezing:

10    * At the place where an expression causes freezing, the type of the
        expression is frozen, unless the expression is an enumeration literal
        used as a discrete_choice of the array_aggregate of an enumeration_-
        representation_clause.

10.a        Reason: We considered making enumeration literals never cause
            freezing, which would be more upward compatible, but examples like
            the variant record aggregate (Discrim => Red, ...) caused us to
            change our mind. Furthermore, an enumeration literal is a static
            expression, so the implementation should be allowed to represent
            it using its representation.

10.b        Ramification: The following pathological example was legal in Ada
            83, but is illegal in Ada 95:

10.c            package P1 is
                    type T is private;
                    package P2 is
                        type Composite(D : Boolean) is
                            record
                                case D is
                                    when False => Cf : Integer;
                                    when True  => Ct : T;
                                end case;
                            end record;
                    end P2;
                    X : Boolean := P2."="( (False,1), (False,1) );
                private
                    type T is array(1..Func_Call) of Integer;
                end;

10.d        In Ada 95, the declaration of X freezes Composite (because it
            contains an expression of that type), which in turn freezes T
            (even though Ct does not exist in this particular case). But type
            T is not completely defined at that point, violating the rule that
            a type shall be completely defined before it is frozen. In Ada 83,
            on the other hand, there is no occurrence of the name T, hence no
            forcing occurrence of T.

10.1/4   * {AI05-0019-1} {AI05-0177-1} {AI12-0157-1} At the place where a
        function call causes freezing, the profile of the function is frozen.
        Furthermore, if a parameter of the call is defaulted, the
        default_expression for that parameter causes freezing. If the function
        call is to an expression function, the return expression of the
        expression function causes freezing.

10.e/3      Reason: {AI05-0019-1} This is the important rule for profile
            freezing: a call freezes the profile. That's because generating
            the call will need to know how the parameters are passed, and that
            will require knowing details of the types. Other uses of
            subprograms do not need to know about the parameters, and thus
            only freeze the subprogram, and not the profile.

10.f/3      Note that we don't need to consider procedure or entry calls,
            since a body freezes everything that precedes it, and the end of a
            declarative part freezes everything in the declarative part.

10.g/4      Ramification: {AI05-0177-1} {AI12-0103-1} {AI12-0157-1} Freezing
            of the return expression of an expression function only needs to
            be considered when the expression function is in the same
            compilation unit and there are no intervening bodys; the end of a
            declarative_part or library package freezes everything in it, and
            a body freezes everything declared before it.

10.2/4   * {AI05-0019-1} {AI05-0177-1} {AI05-0296-1} {AI12-0157-1} At the
        place where a generic_instantiation causes freezing of a callable
        entity, the profile of that entity is frozen unless the formal
        subprogram corresponding to the callable entity has a parameter or
        result of a formal untagged incomplete type; if the callable entity is
        an expression function, the return expression of the expression
        function causes freezing.

10.h/3      Reason: Elaboration of the generic might call the actual for one
            of its formal subprograms, so we need to know the profile and (for
            an expression function) expression.

10.3/4   * {AI05-0177-1} {AI12-0157-1} At the place where a use of the Access
        or Unchecked_Access attribute whose prefix denotes an expression
        function causes freezing, the return expression of the expression
        function causes freezing.

10.i/3      Reason: This is needed to avoid calls to unfrozen expressions.
            Consider:

10.j/3          package Pack is

10.k/3             type Flub is range 0 .. 100;

10.l/3             function Foo (A : in Natural) return Natural is
                      (A + Flub'Size); -- The expression is not frozen here.

10.m/4          {AI12-0005-1}
                   type Bar is access function (A : in Natural) return Natural;

10.n/3             P : Bar := Foo'Access; -- (A)

10.o/3             Val : Natural := P.all(5); -- (B)

10.p/3          end Pack;

10.q/3      If point (A) did not freeze the expression of Foo (which freezes
            Flub), then the call at point (B) would be depending on the
            aspects of the unfrozen type Flub. That would be bad.

11    * At the place where a name causes freezing, the entity denoted by the
        name is frozen, unless the name is a prefix of an expanded name; at
        the place where an object name causes freezing, the nominal subtype
        associated with the name is frozen.

11.a/2      Ramification: {AI95-00114-01} This only matters in the presence of
            deferred constants or access types; an object_declaration other
            than a deferred constant declaration causes freezing of the
            nominal subtype, plus all component junk.

11.b/1      This paragraph was deleted.{8652/0046} {AI95-00106-01}

11.1/1   * {8652/0046} {AI95-00106-01} At the place where an
        implicit_dereference causes freezing, the nominal subtype associated
        with the implicit_dereference is frozen.

11.c/2      Discussion: This rule ensures that X.D freezes the same entities
            that X.all.D does. Note that an implicit_dereference is neither a
            name nor expression by itself, so it isn't covered by other rules.

12    * [ At the place where a range causes freezing, the type of the range is
        frozen.]

12.a        Proof: This is consequence of the facts that expressions freeze
            their type, and the Range attribute is defined to be equivalent to
            a pair of expressions separated by "..".}

13    * At the place where an allocator causes freezing, the designated
        subtype of its type is frozen. If the type of the allocator is a
        derived type, then all ancestor types are also frozen.

13.a        Ramification: Allocators also freeze the named subtype, as a
            consequence of other rules.

13.b        The ancestor types are frozen to prevent things like this:

13.c            type Pool_Ptr is access System.Storage_Pools.Root_Storage_Pool'Class;
                function F return Pool_Ptr;

13.d            package P is
                    type A1 is access Boolean;
                    type A2 is new A1;
                    type A3 is new A2;
                    X : A3 := new Boolean; -- Don't know what pool yet!
                    for A1'Storage_Pool use F.all;
                end P;

13.e        This is necessary because derived access types share their
            parent's pool.

14/3   * {AI05-0019-1} At the place where a profile is frozen, each subtype of
        the profile is frozen. If the corresponding callable entity is a
        member of an entry family, the index subtype of the family is frozen.

14.a/3      This paragraph was deleted.

15    * At the place where a subtype is frozen, its type is frozen. At the
        place where a type is frozen, any expressions or names within the full
        type definition cause freezing; the first subtype, and any component
        subtypes, index subtypes, and parent subtype of the type are frozen as
        well. For a specific tagged type, the corresponding class-wide type is
        frozen as well. For a class-wide type, the corresponding specific type
        is frozen as well.

15.a        Ramification: Freezing a type needs to freeze its first subtype in
            order to preserve the property that the subtype-specific aspects
            of statically matching subtypes are the same.

15.b        Freezing an access type does not freeze its designated subtype.

15.1/3   * {AI95-00341-01} {AI05-0019-1} At the place where a specific tagged
        type is frozen, the primitive subprograms of the type are frozen. At
        the place where a type is frozen, any subprogram named in an
        attribute_definition_clause for the type is frozen.

15.c/2      Reason: We have a language design principle that all of the
            details of a specific tagged type are known at its freezing point.
            But that is only true if the primitive subprograms are frozen at
            this point as well. Late changes of Import and address clauses
            violate the principle.

15.d/2      Implementation Note: This rule means that no implicit call to
            Initialize or Adjust can freeze a subprogram (the type and thus
            subprograms would have been frozen at worst at the same point).

15.e/3      Discussion: {AI05-0019-1} The second sentence is the rule that
            makes it possible to check that only subprograms with convention
            Ada are specified in attribute_definition_clauses without jumping
            through hoops.


                               Legality Rules

16  [The explicit declaration of a primitive subprogram of a tagged type shall
occur before the type is frozen (see 3.9.2).]

16.a        Reason: This rule is needed because (1) we don't want people
            dispatching to things that haven't been declared yet, and (2) we
            want to allow tagged type descriptors to be static (allocated
            statically, and initialized to link-time-known symbols). Suppose
            T2 inherits primitive P from T1, and then overrides P. Suppose P
            is called before the declaration of the overriding P. What should
            it dispatch to? If the answer is the new P, we've violated the
            first principle above. If the answer is the old P, we've violated
            the second principle. (A call to the new one necessarily raises
            Program_Error, but that's beside the point.)

16.b        Note that a call upon a dispatching operation of type T will
            freeze T.

16.c        We considered applying this rule to all derived types, for
            uniformity. However, that would be upward incompatible, so we
            rejected the idea. As in Ada 83, for an untagged type, the above
            call upon P will call the old P (which is arguably confusing).

16.d/3      To be honest: {AI05-0222-1} This rule only applies to "original"
            declarations and not to the completion of a primitive subprogram,
            even though a completion is technically an explicit declaration,
            and it may declare a primitive subprogram.

17  [A type shall be completely defined before it is frozen (see 3.11.1 and
7.3).]

18  [The completion of a deferred constant declaration shall occur before the
constant is frozen (see 7.4).]

18.a/3      Proof: {AI95-00114-01} {AI05-0299-1} The above Legality Rules are
            stated "officially" in the referenced subclauses.

19/1 {8652/0009} {AI95-00137-01} An operational or representation item that
directly specifies an aspect of an entity shall appear before the entity is
frozen (see 13.1).

19.a/1      Discussion: {8652/0009} {AI95-00137-01} From RM83-13.1(7). The
            wording here forbids freezing within the aspect_clause itself,
            which was not true of the Ada 83 wording. The wording of this rule
            is carefully written to work properly for type-related
            representation items. For example, an enumeration_representation_-
            clause is illegal after the type is frozen, even though the
            _clause refers to the first subtype.

19.a.1/2    {AI95-00114-01} The above Legality Rule is stated for types and
            subtypes in 13.1, but the rule here covers all other entities as
            well.

19.b/2      This paragraph was deleted.{AI95-00114-01}

19.c        Discussion: Here's an example that illustrates when freezing
            occurs in the presence of defaults:

19.d            type T is ...;
                function F return T;
                type R is
                    record
                        C : T := F;
                        D : Boolean := F = F;
                    end record;
                X : R;

19.e        Since the elaboration of R's declaration does not allocate
            component C, there is no need to freeze C's subtype at that place.
            Similarly, since the elaboration of R does not evaluate the
            default_expression "F = F", there is no need to freeze the types
            involved at that point. However, the declaration of X does need to
            freeze these things. Note that even if component C did not exist,
            the elaboration of the declaration of X would still need
            information about T - even though D is not of type T, its
            default_expression requires that information.

19.f/3      Ramification: {AI05-0299-1} Although we define freezing in terms
            of the program text as a whole (i.e. after applying the rules of
            Clause 10), the freezing rules actually have no effect beyond
            compilation unit boundaries.

19.g/3      Reason: {AI05-0299-1} That is important, because Clause 10 allows
            some implementation definedness in the order of things, and we
            don't want the freezing rules to be implementation defined.

19.h        Ramification: These rules also have no effect in statements - they
            only apply within a single declarative_part,
            package_specification, task_definition, protected_definition, or
            protected_body.

19.i        Implementation Note: An implementation may choose to generate code
            for default_expressions and default_names in line at the place of
            use. Alternatively, an implementation may choose to generate
            thunks (subprograms implicitly generated by the compiler) for
            evaluation of defaults. Thunk generation cannot, in general, be
            done at the place of the declaration that includes the default.
            Instead, they can be generated at the first freezing point of the
            type(s) involved. (It is impossible to write a purely one-pass Ada
            compiler, for various reasons. This is one of them - the compiler
            needs to store a representation of defaults in its symbol table,
            and then walk that representation later, no earlier than the first
            freezing point.)

19.j        In implementation terms, the linear elaboration model can be
            thought of as preventing uninitialized dope. For example, the
            implementation might generate dope to contain the size of a
            private type. This dope is initialized at the place where the type
            becomes completely defined. It cannot be initialized earlier,
            because of the order-of-elaboration rules. The freezing rules
            prevent elaboration of earlier declarations from accessing the
            size dope for a private type before it is initialized.

19.k        2.8 overrides the freezing rules in the case of unrecognized
            pragmas.

19.l/1      {8652/0009} {AI95-00137-01} An aspect_clause for an entity should
            most certainly not be a freezing point for the entity.


                              Dynamic Semantics

20/2 {AI95-00279-01} The tag (see 3.9) of a tagged type T is created at the
point where T is frozen.


                        Incompatibilities With Ada 83

20.a        RM83 defines a forcing occurrence of a type as follows: "A forcing
            occurrence is any occurrence [of the name of the type, subtypes of
            the type, or types or subtypes with subcomponents of the type]
            other than in a type or subtype declaration, a subprogram
            specification, an entry declaration, a deferred constant
            declaration, a pragma, or a representation_clause for the type
            itself. In any case, an occurrence within an expression is always
            forcing."

20.b        It seems like the wording allows things like this:

20.c            type A is array(Integer range 1..10) of Boolean;
                subtype S is Integer range A'Range;
                    -- not forcing for A

20.d        Occurrences within pragmas can cause freezing in Ada 95. (Since
            such pragmas are ignored in Ada 83, this will probably fix more
            bugs than it causes.)


                            Extensions to Ada 83

20.e        In Ada 95, generic_formal_parameter_declarations do not normally
            freeze the entities from which they are defined. For example:

20.f            package Outer is
                    type T is tagged limited private;
                    generic
                        type T2 is
                            new T with private; -- Does not freeze T
                                                -- in Ada 95.
                    package Inner is
                        ...
                    end Inner;
                private
                    type T is ...;
                end Outer;

20.g        This is important for the usability of generics. The above example
            uses the Ada 95 feature of formal derived types. Examples using
            the kinds of formal parameters already allowed in Ada 83 are well
            known. See, for example, comments 83-00627 and 83-00688. The
            extensive use expected for formal derived types makes this issue
            even more compelling than described by those comments.
            Unfortunately, we are unable to solve the problem that
            explicit_generic_actual_parameters cause freezing, even though a
            package equivalent to the instance would not cause freezing. This
            is primarily because such an equivalent package would have its
            body in the body of the containing program unit, whereas an
            instance has its body right there.


                         Wording Changes from Ada 83

20.h        The concept of freezing is based on Ada 83's concept of "forcing
            occurrences." The first freezing point of an entity corresponds
            roughly to the place of the first forcing occurrence, in Ada 83
            terms. The reason for changing the terminology is that the new
            rules do not refer to any particular "occurrence" of a name of an
            entity. Instead, we refer to "uses" of an entity, which are
            sometimes implicit.

20.i        In Ada 83, forcing occurrences were used only in rules about
            representation_clauses. We have expanded the concept to cover
            private types, because the rules stated in RM83-7.4.1(4) are
            almost identical to the forcing occurrence rules.

20.j        The Ada 83 rules are changed in Ada 95 for the following reasons:

20.k          * The Ada 83 rules do not work right for subtype-specific
                aspects. In an earlier version of Ada 9X, we considered
                allowing representation items to apply to subtypes other than
                the first subtype. This was part of the reason for changing
                the Ada 83 rules. However, now that we have dropped that
                functionality, we still need the rules to be different from
                the Ada 83 rules.

20.l          * The Ada 83 rules do not achieve the intended effect. In Ada
                83, either with or without the AIs, it is possible to force
                the compiler to generate code that references uninitialized
                dope, or force it to detect erroneousness and exception
                raising at compile time.

20.m          * It was a goal of Ada 83 to avoid uninitialized access values.
                However, in the case of deferred constants, this goal was not
                achieved.

20.n          * The Ada 83 rules are not only too weak - they are also too
                strong. They allow loopholes (as described above), but they
                also prevent certain kinds of default_expressions that are
                harmless, and certain kinds of generic_declarations that are
                both harmless and very useful.

20.o/2        * {AI95-00114-01} Ada 83 had a case where an aspect_clause had a
                strong effect on the semantics of the program - 'Small. This
                caused certain semantic anomalies. There are more cases in Ada
                95, because the attribute_definition_clause has been
                generalized.


                        Incompatibilities With Ada 95

20.p/2      {8652/0046} {AI95-00106-01} {AI95-00341-01} Corrigendum: Various
            freezing rules were added to fix holes in the rules. Most
            importantly, implicit calls are now freezing, which make some
            representation clauses illegal in Ada 2005 that were legal (but
            dubious) in Ada 95. Amendment Correction: Similarly, the primitive
            subprograms of a specific tagged type are frozen when the type is
            frozen, preventing dubious convention changes (and address
            clauses) after the freezing point. In both cases, the code is
            dubious and the workaround is easy.


                         Wording Changes from Ada 95

20.q/2      {8652/0009} {AI95-00137-01} Corrigendum: Added wording to specify
            that both operational and representation attributes must be
            specified before the type is frozen.

20.r/2      {AI95-00251-01} Added wording that declaring a specific descendant
            of an interface type freezes the interface type.

20.s/2      {AI95-00279-01} Added wording that defines when a tag is created
            for a type (at the freezing point of the type). This is used to
            specify checking for uncreated tags (see 3.9).


                       Incompatibilities With Ada 2005

20.t/3      {AI05-0019-1} Correction: Separated the freezing of the profile
            from the rest of a subprogram, in order to reduce the impact of
            the Ada 95 incompatibility noted above. (The effects were much
            more limiting than expected.)


                        Wording Changes from Ada 2005

20.u/3      {AI05-0017-1} Correction: Reworded so that incomplete types with a
            deferred completion aren't prematurely frozen.

20.v/3      {AI05-0177-1} Added freezing rules for expression functions; these
            are frozen at the point of call, not the point of declaration,
            like default expressions.

20.w/3      {AI05-0183-1} Added freezing rules for aspect_specifications;
            these are frozen at the freezing point of the associated entity,
            not the point of declaration.

20.x/3      {AI05-0213-1} Added freezing rules for formal incomplete types;
            the corresponding actual is not frozen.


                        Wording Changes from Ada 2012

20.y/4      {AI12-0103-1} {AI12-0132-1} Corrigendum: Clarified when and what
            an expression_function_declaration that is a completion or that is
            the target of a renames-as-body freezes. This is formally an
            incompatibility, but as all known implementations freeze
            expression functions more aggressively than allowed by either the
            old or new wording, practically this will be an extension.

Generated by dwww version 1.15 on Fri May 24 02:36:53 CEST 2024.