!standard 3.2.4(1/5) 21-01-29 AI12-0419-1/03 !standard 3.2.4(29.5/4) !standard 3.9.2(1/5) !standard 4.2.1(6/5) !standard 4.10(4/5) !standard 4.10(7/5) !standard 4.10(19/5) !standard 7.3.2(3/4) !standard 7.3.3(2/5) !standard 12.5.1(21/3) !standard 13.1(15.9/5) !standard 13.1.1(18.3/5) !standard 13.13.2(8.1/3) !standard 13.13.2(9/3) !standard 13.13.2(25/3) !standard 13.13.2(25.1/2) !standard 13.13.2(25.1/2) !standard 13.13.2(42/2) !class Amendment 21-01-14 !status Amendment 1-2012 21-01-21 !status ARG Approved 16-0-0 21-01-20 !status work item 21-01-14 !status received 21-01-14 !priority Low !difficulty Medium !subject Aspect inheritance and reemergence !summary Type-related and subtype-specific aspects that can mention subprograms by name fall into different categories relating to whether and how they are inherited, and whether for a formal untagged type, the operations of the ancestor reemerge in an instance, or the aspects of the actual are always used: 1) implicitly composed Implicitly composed aspects are not inherited per se, but the aspect for a derived type is implicitly composed from that of its parent type. The aspects of an ancestor never "reemerge" in a generic; the actual type's "actual" aspect definition is invoked. This makes sense because these aspects are generally defined for private types, and in that case there is no ancestor aspect to reemerge. 2) additive Additive aspects are not inherited, but they "apply" to their descendants, using a "notional formal derived type" model. In a generic, the type's "actual" aspect definition is invoked as appropriate, even if untagged. As with the implicitly composed aspects, these are meaningful on private types, so reemergence of an ancestor's aspect would not make sense. 3) nonoverridable Nonoverridable aspects are inherited, but cannot be overridden except with a "confirming" definition which matches that of the parent type as defined in 13.1. On the other hand, the named subprograms can be overridden, and that is the way to alter the effect of a nonoverridable aspect in a derived type. For a formal untagged derived type, the ancestor's nonoverridable aspects, if any, reemerge, which is not surprising because the primitive subprograms of the untagged ancestor reemerge as well. Ancestor aspects of formal tagged types never reemerge thanks to the rule that the actual type's run-time tag controls which body is executed. For uniformity, we change the description of stream attributes of untagged types to use the "implicitly composed" terminology rather than inheritance, to better match what happens with tagged stream attributes. This is not intended to change the semantics in any way; it is just a presentation change that hopefully clarifies the semantics. The Put_Image aspect is considered to be implicitly composed as well. The user-defined literal aspects are nonoverridable. !question Is the Put_Image aspect inherited by a derived type? (Not exactly; it is defined by default by a call on the parent's Put_Image, composed with, if tagged, the Put_Image of any extension components.) If not, what happens with untagged derived types? (They use an implicitly defined Put_Image that calls the parent Put_Image.) Does the Put_Image of the ancestor of a formal derived type reemerge in a generic instance, or is the actual type's Put_Image used? (Actual type.) What are the general rules for inheritance and reemergence of operational aspects? (This AI attempts to clarify them.) What are the inheritance and re-emergence rules for the user-defined literal aspects? (They are nonoverridable.) !recommendation See !summary. !wording [relative to AARM 202X Draft 27] Modify 3.2.4(1/5): The language-defined predicate aspects Static_Predicate and Dynamic_Predicate may be used to define properties of subtypes. A predicate specification is an aspect_specification for one of the two predicate aspects. General rules for aspects and aspect_specifications are found in Clause 13 (13.1 and 13.1.1 respectively). The predicate aspects are assertion aspects (see 11.4.2).{ [Redundant: The predicate aspects are not inherited, but their effects are additive, as defined below.]} Modify 3.2.4(29.5/4): * if S is a first subtype, the value is tested to determine whether it satisfies the predicates of the parent and progenitor subtypes (if any) of S (in an arbitrary order){, after a (view) conversion of the value to the corresponding parent or progenitor type}; Modify 3.9.2(1/5): The primitive subprograms of a tagged type, the subprograms declared by formal_abstract_subprogram_declarations, the [subprograms identified by the user-defined literal aspects]{Put_Image attribute} of a specific tagged type (see [4.2.1]{4.10}), and the stream attributes of a specific tagged type that are available (see 13.13.2) at the end of the declaration list where the type is declared are called dispatching operations. [... rest as before] Modify 4.2.1(6/5): User-defined literal aspects are [inherited according to the rules given in 13.1]{ nonoverridable (see 13.1.1)}. Modify 4.10(4/5): The Put_Image attribute may be specified for any specific type T either via an attribute_definition_clause or via an aspect_specification specifying the Put_Image aspect of the type.{ [Redundant: The Put_Image aspect is not inherited, but rather is implicitly composed for derived types, as defined below.]} Modify 4.10(5/5) (this makes three paragraphs out of one): The behavior of the default implementation of S'Put_Image depends on the class of T.{ For an untagged derived type, the default implementation of T'Put_Image invokes the Put_Image for its parent type on a conversion of the parameter of type T to the parent type. }For {a nonderived}[an] elementary type, the implementation is equivalent to: Make each paragraph 4.10(8/5-12/5) into a bullet. Move a modified version of 4.10(17/5) and 4.10(18/5), as a single paragraph, after 4.10(12/5): For a type extension, the default implementation of T'Put_Image depends on whether there exists a noninterface ancestor of T (other than T itself) for which the Put_Image aspect has been [Redundant: [explicitly]{directly}] specified. If so, then T'Put_Image will generate an image based on extension aggregate syntax where the ancestor type of the extension aggregate is the nearest ancestor type whose Put_Image aspect has been specified. If no such ancestor exists, then the default implementation of T'Put_Image is the same as described below for {a nonderived}[an untagged] record type. Discussion: This might generate an image such as "(This Text Was User-Generated with C1 => 123, C2 => 456)" where the "This Text was User-Generated" portion of the text was generated by the call to the user-specified Put_Image routine {for the ancestor}. Add after 4.10(12/5) [and the above moved paragraph]: For a specific, nonderived composite type: Move a modified and bulleted version of 4.10(15/5) after the above paragraphs: {* If the default implementation of Put_Image writes components, the}[The] order in which components are written [for a composite type ]is the same canonical order in which components of a composite type T are written out by the default implementation of T'Write. Redundant[This is also the order that is used in determining the meaning of a positional aggregate of type T.] Bullet 4.10(13/5). Indent 4.10(14/5) [it is logically part of the preceding paragraph]. [4.10(15/5), 4.10(17/5), and 4.10(18/5) were moved above; 4.10(16/5) is moved below.] Modify (and bullet) 4.10(19/5): {*} For {a}[an untagged] untagged record type{ (or, as indicated above, a type extension with no noninterface ancestor specifying Put_Image)}, a specific tagged record type other than a type extension which meets the criteria described in the previous paragraph, or a protected type, the default implementation of T'Put_Image generates an image based on named (not positional) record aggregate syntax (except that for a protected type, the initial left parenthesis is followed by "PROTECTED with "). Component names are displayed in upper case, following the rules for the image of an enumeration value. Component values are displayed via calls to the component type's Put_Image procedure. Indent 4.10(20/5) [it is logically part of the preceding paragraph]. Bullet 4.10(21/5) and 4.10(22/5). Move 4.10(16/5) and the associated AARM notes after 4.10(23/5). [This is not bulleted]. Modify 7.3.2(3/4): Type_Invariant'Class This aspect shall be specified by an expression, called an invariant expression. Type_Invariant'Class may be specified on a private_type_declaration, or a private_extension_declaration, or a full_type_declaration for an interface type. Type_Invariant'Class determines a class-wide type invariant for a tagged type. {[Redundant: The Type_Invariant'Class aspect is not inherited, but its effects are additive, as defined below.]} Modify 7.3.3(2/5): Default_Initial_Condition This aspect shall be specified by an expression, called a default initial condition expression. Default_Initial_Condition may be specified on a private_type_declaration, a private_extension_declaration, a formal_private_type_definition, or a formal_derived_type_definition. {[Redundant: The Default_Initial_Condition aspect is not inherited, but its effects are additive, as defined below.]} Add after 12.5.1(21/3): In an instance, the implicitly composed and additive aspects (see 13.1.1) of a formal type are those of the actual; for a nonoverridable aspect, a formal derived type inherits the aspect if the ancestor or any progenitor has the aspect, according to the rules given in 13.1. Delete 13.1(15.9/5) [NOTE: it is no longer relevant because implicitly-composed aspects are not inherited, even for untagged derived types. Here is what it currently says: 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).] Modify 13.1.1(18.3/5): Certain type-related aspects are defined to be /nonoverridable/{; all such aspects are inherited by derived types according to the rules given in 13.1. Any legality rule associated with a nonoverridable aspect is re-checked for the derived type, if the derived type is not abstract. Certain type-related and subtype-specific aspects are defined to be /additive/; such aspects are not inherited, but they can /apply/ to the types derived from, or the subtypes based on, the original type or subtype, as defined for each such aspect. Finally, certain type-related aspects are /implicitly composed/; such aspects are not inherited, but rather a default implementation for a derived type is provided, as defined for each such aspect, based on that of its parent type, presuming the aspect for the parent type is available where the derived type is declared, plus those of any new components added as part of a type extension.} Delete 13.13.2(8.1/3) and the associated AARM note (it will be moved below). Modify 13.13.2(9/3): [Splitting into two paragraphs.] For {nonderived} 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 {nonderived} composite types, the Write or Read attribute for each component (excluding those, if any, that are not components of the nominal type of the object) 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. {For untagged derived types, the Write (resp. Read) attribute invokes the corresponding attribute of the parent type, if the attribute is available for the parent type.} Modify 13.13.2(25/3): For an untagged derived type, {the default implementation of} the Output (resp. Input) attribute {invokes the corresponding attribute of the parent type,} [inherited according to the rules given in 13.1] if the attribute is [[Redundant: 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.] {For any other type, the default implementations of the Output and Input attributes, where available, execute as follows:} Delete 13.13.2(25.1/2): [NOTE: Its content has been moved into 25/3 above.] Modify 13.13.2(42/2): T is a limited untagged derived type, and the attribute [was inherited] {is available} for the {parent} type. Modify 13.13.2(44/2): The attribute has been specified via an attribute_definition_clause{ or aspect_specification}, and the attribute_definition_clause{ or aspect_specification} is visible. Modify 13.13.2(47/2): The attribute has been specified via an attribute_definition_clause{ or aspect_specification}, and the attribute_definition_clause{ or aspect_specification} is visible. Modify 13.13.2(49.1/4): Unless {available for}[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. !discussion Almost all of the above wording is intended to clarify the existing inheritance and reemergence rules, rather than establish new rules. However, there are two significant changes: 1) We have said that the Put_Image aspects are not inherited, but are rather implicitly composed. Before we were silent on what happened with an untagged derived type. 2) We treat user-defined literal aspects as nonoverridable. The current wording suggests that they are a separate operation, but says that they are inherited as defined in 13.1. This presumably was referring to stream-attribute style inheritance, although nonoverridable inheritance is also (partially) defined there. We considered using a form of "implicitly composed" inheritance for user-defined literals. This would have the advantage that an extension could have the literal operation and the originally associated operation do different things (which could be necessary if the named operation is useful user operation in its own right, such as the From_String conversion originally defined for BigNums). But it would have the disadvantage that for a non-null type extension, the aspect is *required* to be re-specified, again, even if it is to just use the overriding of the previously named primitive. That would necessary as such functions are required to be overridden, and a similar rule would be needed for such aspects. !examples type T is private with Integer_Literal => From_String; function From_String(S : String) return T; ... type T2 is new T; overriding function From_String(S : String) return T2; The overriding From_String is used for converting integer literals for T2. In the rejected alternative, the overriding From_String would not be used, unless you repeat the "with Integer_Literal => From_String" on the declaration of T2. In this alternative, you would have had the ability to have T2 use a different operation for converting literals. As defined, you are limited to using "From_String" in all descendants, because the aspect is nonoverridable. !corrigendum 3.2.4(1/3) @drepl The language-defined @i Static_Predicate and Dynamic_Predicate may be used to define properties of subtypes. A @i is an @fa for one of the two predicate aspects. General rules for aspects and @fas are found in Clause 13 (13.1 and 13.1.1 respectively). @dby The language-defined @i Static_Predicate and Dynamic_Predicate may be used to define properties of subtypes. A @i is an @fa for one of the two predicate aspects. General rules for aspects and @fas are found in Clause 13 (13.1 and 13.1.1 respectively). The predicate aspects are assertion aspects (see 11.4.2). The predicate aspects are not inherited, but their effects are additive, as defined below. !corrigendum 3.2.4(29.5/4) @drepl @xinbull is a first subtype, the value is tested to determine whether it satisfies the predicates of the parent and progenitor subtypes (if any) of @i (in an arbitrary order);> @dby @xinbull is a first subtype, the value is tested to determine whether it satisfies the predicates of the parent and progenitor subtypes (if any) of @i (in an arbitrary order), after a (view) conversion of the value to the corresponding parent or progenitor type;> !corrigendum 3.9.2(1/2) @drepl The primitive subprograms of a tagged type, the subprograms declared by @fas, and the stream attributes of a specific tagged type that are available (see 13.13.2) at the end of the declaration list where the type is declared are called @i. A dispatching operation can be called using a statically determined @i tag, in which case the body to be executed is determined at compile time. Alternatively, the controlling tag can be dynamically determined, in which case the call @i to a body that is determined at run time; such a call is termed a @i. As explained below, the properties of the operands and the context of a particular call on a dispatching operation determine how the controlling tag is determined, and hence whether or not the call is a dispatching call. Run-time polymorphism is achieved when a dispatching operation is called by a dispatching call. @dby The primitive subprograms of a tagged type, the subprograms declared by @fas, the Put_Image attribute (see 4.10) of a specific tagged type, and the stream attributes of a specific tagged type that are available (see 13.13.2) at the end of the declaration list where the type is declared are called @i. A dispatching operation can be called using a statically determined @i tag, in which case the body to be executed is determined at compile time. Alternatively, the controlling tag can be dynamically determined, in which case the call @i to a body that is determined at run time; such a call is termed a @i. As explained below, the properties of the operands and the context of a particular call on a dispatching operation determine how the controlling tag is determined, and hence whether or not the call is a dispatching call. Run-time polymorphism is achieved when a dispatching operation is called by a dispatching call. !corrigendum 4.2.1(0) @dinsc ** Force a conflict; the actual changes are in the conflict file. ** !corrigendum 4.10(0) @dinsc ** Force a conflict; the actual changes are in the conflict file. ** !corrigendum 7.3.2(3/4) @drepl @xhang<@xterm This aspect shall be specified by an @fa, called an @i. Type_Invariant'Class may be specified on a @fa, a @fa, or a @fa for an interface type. Type_Invariant'Class determines a @i for a tagged type.> @dby @xhang<@xterm This aspect shall be specified by an @fa, called an @i. Type_Invariant'Class may be specified on a @fa, a @fa, or a @fa for an interface type. Type_Invariant'Class determines a @i for a tagged type. The Type_Invariant'Class aspect is not inherited, but its effects are additive, as defined below.> !corrigendum 7.3.3(0) @dinsc ** Force a conflict; the actual changes are in the conflict file. ** !corrigendum 12.5.1(21/3) @dinsa In an instance, the copy of an implicit declaration of a primitive subprogram of a formal derived type declares a view of the corresponding primitive subprogram of the ancestor or progenitor of the formal derived type, even if this primitive has been overridden for the actual type and even if it is never declared for the actual type. When the ancestor or progenitor of the formal derived type is itself a formal type, the copy of the implicit declaration declares a view of the corresponding copied operation of the ancestor or progenitor. In the case of a formal private extension, however, the tag of the formal type is that of the actual type, so if the tag in a call is statically determined to be that of the formal type, the body executed will be that corresponding to the actual type. @dinst In an instance, the implicitly composed and additive aspects (see 13.1.1) of a formal type are those of the actual; for a nonoverridable aspect, a formal derived type inherits the aspect if the ancestor or any progenitor has the aspect, according to the rules given in 13.1. !corrigendum 13.1(15.2/2) @ddel 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). !corrigendum 13.1.1(18.2/4) @drepl Certain type-related aspects are defined to be @i; all such aspects are specified using an @fa that is a @fa. @dby Certain type-related aspects are defined to be @i; all such aspects are inherited by derived types according to the rules given in 13.1. Any legality rule associated with a nonoverridable aspect is re-checked for the derived type, if the derived type is not abstract. Certain type-related and subtype-specific aspects are defined to be @i; such aspects are not inherited, but they can @i to the types derived from, or the subtypes based on, the original type or subtype, as defined for each such aspect. Finally, certain type-related aspects are @i; such aspects are not inherited, but rather a default implementation for a derived type is provided, as defined for each such aspect, based on that of its parent type, presuming the aspect for the parent type is available where the derived type is declared, plus those of any new components added as part of a type extension. !corrigendum 13.13.2(8.1/3) @ddel 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 @i is declared. For a tagged derived type, these attributes are not inherited, but rather the default implementations are used. !corrigendum 13.13.2(9/3) @drepl For elementary types, Read reads (and Write writes) the number of stream elements implied by the Stream_Size for the type @i; 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 @i is an array type. If @i is a discriminated type, discriminants are included only if they have defaults. If @i 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 @i is available anywhere within the immediate scope of @i, and the attribute of the parent type or the type of any of the extension components is not available at the freezing point of @i, then the attribute of @i shall be directly specified. @dby For nonderived elementary types, Read reads (and Write writes) the number of stream elements implied by the Stream_Size for the type @i; the representation of those stream elements is implementation defined. For nonderived composite types, the Write or Read attribute for each component (excluding those, if any, that are not components of the nominal type of the object) 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 @i is an array type. If @i is a discriminated type, discriminants are included only if they have defaults. If @i 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 @i is available anywhere within the immediate scope of @i, and the attribute of the parent type or the type of any of the extension components is not available at the freezing point of @i, then the attribute of @i shall be directly specified. For untagged derived types, the Write (resp. Read) attribute invokes the corresponding attribute of the parent type, if the attribute is available for the parent type. !corrigendum 13.13.2(25/3) @drepl 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 @i is declared. For a tagged derived type, these attributes are not inherited, but rather the default implementations are used. @dby For an untagged derived type, the default implementation of the Output (resp. Input) attribute invokes the corresponding attribute of the parent type, if the attribute is available for the parent type. For any other type, the default implementations of the Output and Input attributes, where available, execute as follows: !corrigendum 13.13.2(25.1/2) @ddel The default implementations of the Output and Input attributes, where available, execute as follows: !corrigendum 13.13.2(42/2) @drepl @xbullet<@i is a limited untagged derived type, and the attribute was inherited for the type.> @dby @xbullet<@i is a limited untagged derived type, and the attribute is available for the parent type.> !corrigendum 13.13.2(44/2) @drepl @xbullet, and the @fa is visible.> @dby @xbullet or @fa, and the @fa or @fa is visible.> !corrigendum 13.13.2(47/2) @drepl @xbullet, and the @fa is visible; or> @dby @xbullet or @fa, and the @fa or @fa is visible; or> !corrigendum 13.13.2(49.1/4) @drepl 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. @dby Unless available for 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. !ASIS No ASIS effect. !ACATS test ACATS B- and C-Tests are needed to check that Put_Image works properly for derived types. We also need ACATS B- and C-Tests are needed to check that the user-defined literal aspects are nonoverrideable. No tests are needed for other aspects as no semantic change is intended. !appendix From: Randy Brukardt Sent: Monday, February 1, 2021 09:23 PM In AI12-0419-1, the placement of the untagged derived type rule (4.10(7/5)) was in the middle of rules that apply only to elementary types. Tucker also proposed moving the record type rules to a location under a heading "for all elementary types". The next elementary record type I encounter will be the first. :-) Some reorganization is needed to fix this. This mistake happened because the rules 4.10(8/5) to 4.10(12/5) are all underneath the heading 4.10(7/5), but that was not obvious as there is no bullets or indentation used. After discussion with Tucker, we decided that most of these paragraphs should have bullets. These changes rearrange (and indent and bullet) many of the paragraphs in 4.10, however, the actual wording is barely changed (and most of those changes were in the original, approved, AI). This was processed as an editorial review change to AI12-0419-1. No action is required unless you want to object to some part of this change. A detailed list of changes and the actual !wording for the AI follows this note. --- (1) Split 4.10(5/5) into two parts. (2) Put the new paragraph about untagged derived types in the middle of that paragraph. (3) Bulleted the subsidiary paragraphs to the "For elementary types..." so it is obvious that they are a different level than the others. (4) Reorganized what was 4.10(15/5) to start with "For all composite types...", as it is supposed to be a blanket rule but it is getting lost - following the intended reading of this section, it would only belong to array types. (5) Added an intro "For a specific, nonderived composite type:" as a counterpart to the elementary type rule. Moved the type extension paragraph (which was 4.10(17/5) & 4.10(18/5)) before this introduction. (6) Bulleted the subsidiary paragraphs to this new header. (paragraphs that were 4.10(15/5), 4.10(13/5), 4.10(14/5) [not bulleted, it is part of the preceding paragraph], 4.10(21/5), 4.10(22/5) [also not bulleted], 4.10(21/5), 4.10(22/5), and 4.10(23/5) [not bulleted, of course]). (7) Put the class-wide paragraph (was 4.10(16/5)) at the end of all of this (not bulleted or indented). --- Here is the entire new !wording for these paragraphs. [See version /03 of this AI - Editor.] --- A following message shows this entire part of the clause as reformatted (in HTML). [Not recorded here - Editor.] **************************************************************** From: Randy Brukardt Sent: Thursday, February 4, 2021 01:53 AM In AI12-0419-1, Tucker had recommended a reordering of parts of the paragraphs 13.13.2(8.1/3), 13.13.2(8.2/2), 13.13.2(9/3). There are a couple of issues raised by this reordering, the most important of which is that a use of the term "canonical order" would appear before the definition of the term. It occurred to me that much less reordering is needed to get the correct result, we just need a few strategic additions of "nonderived", and the addition of a bit of 13.13.2(8.1/3). When Tucker reviewed these changes, he suggested splitting 13.13.2(9/3) in half, as it has grown too large to be comfortably readable. Thus, I'm replacing the changes in the AI for 13.13.2(8.1/3), 13.13.2(8.2/2), 13.13.2(9/3) with the following: Delete 13.13.2(8.1/3) and the associated AARM note (it will be moved below). Modify 13.13.2(9/3): [Splitting into two paragraphs.] For {nonderived} 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 {nonderived} composite types, the Write or Read attribute for each component (excluding those, if any, that are not components of the nominal type of the object) 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. {For untagged derived types, the Write (resp. Read) attribute invokes the corresponding attribute of the parent type, if the attribute is available for the parent type.} [Note: Paragraph 13.13.2(8.2/2) is unmodified by these changes and thus is no longer mentioned in the AI.] --- There are a couple of other minor issues. The definition here is based on "availability", which is based on visibility of the attribute_definition_clause or aspect_specification. The old definition was based on inheritance at the point of the type declaration. This difference is a minor extension, in that a type derived from a private type can have a stream attribute available when the full type of the parent is visible. This can happen in child packages, and avoids an anomoly where the full definitions of all the types are visible but the stream attributes still cannot be used. In order that all available stream attributes are well-defined, the wording "at the point of the type T" was dropped from both 13.13.2(9/3) [that was done above] and from 13.13.2(25/2). --- 13.13.2(49.1/4) has a left-over "inherited from"; this is replaced by "available for". --- Finally, the definition of availability includes the following: The attribute has been specified via an attribute_definition_clause, and the attribute_definition_clause is visible. However, there is no similar rule for aspect_specifications. We updated the definition of "visibility" to include aspect_specifications when those were introduced in Ada 2012. But somehow we never updated the rules that *used* that definition. I'd guess that someone thought that the usual equivalence was good enough; but this rule is in terms of the syntax definition, and there is certainly no equivalence of syntax between attribute_definition_clauses and aspect_specifications. So, I replaced 13.13.2(44/2) and 13.13.2(47/2) with: The attribute has been specified via an attribute_definition_clause{ or aspect_specification}, and the attribute_definition_clause{ or aspect_specification} is visible. --- I've processed all of these as Editorial Review changes on AI12-0419-1. These changes are all making the intent of the approved AI explicit; there is no change in semantics intended. I'll note that anyone can request a Letter Ballot if they feel the changes are too extensive. P.S. I'm finally done with this AI, which I think is the last nasty one. **************************************************************** From: Tucker Taft Sent: Thursday, February 4, 2021 08:36 AM Looks good, Randy. Nice to avoid the reordering of all of the paragraphs. ****************************************************************