Version 1.3 of ai12s/ai12-0427-1.txt

Unformatted version of ai12s/ai12-0427-1.txt version 1.3
Other versions for file ai12s/ai12-0427-1.txt

!standard 3.5(56.4/3)          21-05-27 AI12-0427-1/03
!standard 3.6(22.2/3)
!standard 4.2.1(0/5)
!standard 4.3.5(0/5)
!standard 4.5.10(0/5)
!standard 4.10(0/5)
!standard 8.5(5)
!standard 8.6(17.1/5)
!standard 9.10.1(26/5)
!standard 13.1(10/5)
!standard 13.1(13.1/3)
!standard 13.1.1(21/3)
!standard 13.1.1(22/3)
!standard 13.3(6)
!standard 13.13.2(51/3)
!standard B.3(65.1/5)
!class Amendment 21-05-07
!status Amendment 1-2012 21-05-07
!status work item 21-05-07
!status received 21-05-07
!priority Low
!difficulty Easy
!subject Fixups from WG 9 review
!summary
(1) Add rules about the subtypes of Put_Image and the propagation of exceptions from implicit calls to Put_Image.
(2) Delete 8.5(5); it is not true in Ada 202x (and part of it was not true in Ada 2005 or Ada 2012, either).
(3) Add "unless otherwise specified" to the second sentence of 8.6(17.1/5).
(4) Add a case for "aggregates" to 13.1.1(19-22/3).
(5) Generalize 13.3(6) (moving it after 13.1(13.1/3)) and 13.13.2(51/3) to apply to aspect_specifications as well as attribute_definition clauses.
(6) Remove "no primitive subprograms" from 3.5(56.4/3) and 3.6(22.2/3).
(7) Drop the text added by AI12-0411-1 to B3.(65.1/5).
(8) Clarify the second sentence of 4.5.10(34/5).
(9) Replace the original 13.1(10) in the case of primitive subprogram parameters that are passed by reference and thus cannot be converted to a different representation.
(10) Add a special case to 3.5(56.4/3) to prevent problems with the inheritance of routines that would be illegal if called explicitly.
(11) In 4.3.5(6/5), change the matching to require "exactly one" and allow any signed integer type for the parameter if any.
(12) Clarify that the Implementation Permission in 9.10.1 also applies to All_xxx_Checks policies.
(13) Clarify what is passed to xxx_Literal functions.
!problem
(1) Stream-oriented attributes define the subtype of the parameter of the associated subprograms with 13.13.2(51/3). We don't have any similar rule for Put_Image in 4.10. The definition of Put_Image seems to suggest that the parameter is of type T, but type do not have names in Ada -- one always has to specify a subtype.
Additionally, the RM we doesn't mention that the implicit calls of Put_Image propagate any exceptions (including those caused by a subtype check failure).
(2) 8.5(5) says that an object of an anonymous access type cannot be renamed. However, it seems to me that the second alternative in 8.5.1(1/5), the "access_definition" case, does allow such a renaming. Similarly, 8.5(5) says that a single task or protected object cannot be renamed since the corresponding type is anonymous, but as we can now omit the subtype_mark from the object_renaming_declaration, it seems that such entities can be renamed. Either I am wrong, or the statements in 8.5(5) are wrong.
(3) The nominal (sub)type specified in 8.6(17.1/5) for the "current instance" value seems to be overridden in 7.3.2(5/4) for the aspect Type_Invariant'Class, and in 7.3.3(4/5) for the aspect Default_Initial_Condition, where different types ("NT") are specified for the current instance. This apparent contradiction should be addressed in some way.
(4) In RM 13.1.1(19/3-22/3) we have:
Depending on which aspect is identified by the aspect_mark, an aspect_definition specifies:
* a name that denotes a subprogram, object, or other kind of entity;
* 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
* an identifier specific to the aspect.
This is relatively old wording, and doesn't mention "aggregate" which is of course a kind of expression, but in newer wording is called out separately, and it is certainly misleading to talk about it being evaluated to produce a "single value."
(5) Paragraphs 13.3(6) and 13.13.2(51/3) give requirements on subprograms specified for attributes (aspects) via an attribute_definition_clause. There is no rule that does that for aspects specified via aspect_specifications.
(6) 3.5(56.4/3) says:
If a derived type with no primitive subprograms inherits a boolean Default_Value aspect, the aspect may be specified to have any value for the derived type.
It is likely that the "with no primitive subprograms" was included to ensure that we didn't unintentionally override 13.1(10) with this rule. However, Ada 202x removes the bulk of 13.1(10) (which mostly was intended to avoid expensive implicit conversions -- but the effect was to prevent programmers from writing derived types that they needed even if the expensive conversion was not a problem). This means this rule as written is a wart, as it seems to prevent non-confirming Default_Value aspects in the case of a type with primitive subprograms.
3.6(22.2/3) has similar wording.
(7) We have added C_bool to Interfaces.C, which is defined to be equivalent to C's "bool" (or "_Bool"). It now seems misleading to say that Ada's Standard.Boolean type "corresponds" to the C bool type. The point of introducing C_bool was so that you could be certain that you had a type compatible with C, and there was no guarantee that, for example, a record component of type Standard.Boolean would match a C struct component of type "bool."
The current state of RM B.3(65.1/5) is
An Ada enumeration type corresponds to a C enumeration type with corresponding enumeration literals having the same internal codes, provided the internal codes fall within the range of the C int type. The Ada Boolean type corresponds to the C bool type.
That last sentence was not present when this paragraph was added, which originated from AI12-0135-1. The last sentence came from AI12-0411-1, which defined Interfaces.C.C_bool. That last sentence seems to miss the whole point of the addition of C_bool, namely, that there is no requirement that the Ada Boolean type itself corresponds to the C bool type.
(8) 4.5.10 (34/5) says:
For a parallel reduction expression, it is a bounded error if the reducer subprogram is not associative. That is, for any arbitrary values of subtype Value_Type A, B, C and a reducer function R, the result of R (A, R(B, C)) should produce a result equal to R (R (A, B), C)). The possible consequences are Program_Error, or a result that does not match the equivalent sequential reduction expression due to the order of calls on the reducer subprogram being unspecified in the overall reduction. Analogous rules apply in the case of a reduction procedure.
The second sentence is misleading in that it is explaining what associative means while the first sentence talks about being not associative.
(9) We have relaxed the rules relating to specifying type-related representation aspects when there are primitives that might be inherited by derived types with a different representation. However, we did not take into account that some parameters are necessarily passed by reference, even if the type itself is not a by-reference type. Such parameters cannot easily be converted automatically when calling an inherited subprogram.
(10) Paragraphs 6.4.1(5.1/5) through 6.4.1(5.4/4) define a Legality check for some scalar view conversions passed to OUT mode parameters.
When a type is derived, any inherited subprograms are called with the actual parameters of the new type view converted to the parent type. This can cause an anomaly, in that an explicit call would be illegal while calling an inherited routine (which makes the same call implicitly) is legal.
Tucker notes that 6.4.1(15.1/5) says that this view conversion raises Program_Error. Therefore, there is no language bug in that code that does not follow the principles cannot be executed. OTOH, the rule Tucker refers to was only intended to be used in generic bodies (and there is an AARM note to that effect). So implementers and users alike are likely to be confused.
Moreover, we have a Language Design Principle (admittedly, not always followed) that a construct which will always raise an exception should be detected at compile-time. So it seems that a Legality Rule is missing here.
(11) The optional parameter of the Empty function is required in 4.3.5(6/5) to be of type (Standard.) Integer. However, the language-defined containers use Empty functions that have an Ada.Containers.Count_Type parameter, and that does not match this specification.
(12) Are these permissions granted also when the (stronger) policies All_Parallel_Conflict_Checks or All_Tasking_Conflict_Checks apply? It is said earlier in this subclause that these stronger policies "include" the restrictions imposed by the weaker (Known_...) policies, but it is not clear that specifying the stronger policies implies that the weaker policies also "apply", which is the condition now given for these permissions.
(13) 4.2.1(7/5) says:
... The actual parameter of this notional call is a string_literal having the textual representation of the original (numeric or string) literal.
Does the textual representation of a string literal include the quotes on either end? And what about doubled quotation marks occurring in the middle? Based on the example of Roman_Number, I would guess the answer is the enclosing quotes are removed, and a doubled quotation mark becomes a single quotation mark, but that is not clear from this rule.
Additionally, how can a string literal have the same textual representation as a numeric literal? At a minimum it needs enclosing quotation marks. This needs to be better specified.
!proposal
(1) Add appropriate wording.
(2) Delete 8.5(5).
(3) Add "unless otherwise specified" to the second sentence of 8.6(17.1/5).
(4) Add an extra bullet for "aggregates".
(5) (See summary.)
(6) (See summary.)
(7) (See summary.)
(8) Add clarifying text at the end of the second sentence of 4.5.10(34/5).
(9) Add a definition of a "by-reference primitive", and disallow nonconfirming representation clauses if any of those are present.
(10) Add a special case to 3.5(56.4/3) preventing specification of Default_Value if this problem can happen.
(11) Allow the optional parameter to be of any integer type. Also, require exactly one function to match this, to avoid issues if there are multiple routines that match these profiles.
(12) Add All_Parallel_Conflict_Checks or All_Tasking_Conflict_Checks to the permission of 9.10.1(26/5).
(13) Clarify what is passed to xxxx_Literal functions.
!wording
[Editor's note: These changes have been applied to Draft 30 of the RM, even though they are not yet approved, in order that the draft reflect as much of the accepted WG 9 comments as possible.]
(1) Add after 4.10(4/5):
For an aspect_specification or attribute_definition_clause specifying Put_Image, the subtype of the Arg parameter shall be the first subtype or the base subtype if scalar, and the first subtype if not scalar.
[Editor's note: This is really a Legality Rule, but we don't currently have such a section here. If we added one, the rule would be far away from the place where it makes sense. Note that stream-oriented attributes don't have Legality Rules section either.]
Add to the end of each of 4.10(28.2/5), 4.10(31/5), 4.10(34/5):
Redundant[Any exception propagated by the call of S'Put_Image is propagated.]
[Editor's note: There is no attempt to have such wording for the default implementations of the stream-oriented attributes, so we make no attempt to do that here, either. All such wording is redundant, since it follows directly from the definition of exception propagation in 11.4.]
(2) Delete 8.5(5).
(3) Modify 8.6(17.1/5):
Within an aspect_specification for a type or subtype, the current instance represents a value of the type; it is not an object. {Unless otherwise specified, the}[The] nominal subtype of this value is given by the subtype itself (the first subtype in the case of a type_declaration), prior to applying any predicate specified directly on the type or subtype. If the type or subtype is by-reference, the associated object of the value is the object associated (see 6.2) with the evaluation of the usage name.
(4) Modify 13.1.1(21/3):
* an expression{ (other than an aggregate)}, 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]
Modify 13.1.1(22/3):
* an identifier specific to the aspect{; or
* an aggregate, which is positional or named, and is composed of elements of any of these four kinds of constructs}.
(5) Add after 13.1(13.1/3):
When specifying an aspect that denotes a subprogram, the profile of the subprogram shall be mode conformant with the one required for the aspect, and the convention shall be Ada. Additional requirements are defined for particular aspects.
AARM Ramification: As well as applying to aspect_specifications, this rule applies to attribute_definition_clauses for those aspects that have associated attributes.
This rule implies, for example, that if one writes:
type T is ... with Read => R;
R has to be a procedure with two parameters with the appropriate subtypes and modes as shown in 13.13.2. End AARM Ramification.
[Editor's note: The latter half of this AARM Ramification is from the existing text, modified to use an aspect_specification.]
Delete 13.3(6) and the associated notes (the rule above replaces it).
Modify 13.13.2(51/3):
For an attribute_definition_clause {or aspect_specification} 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.
Modify AARM 13.13.2(51.b/3):
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.{ For the same reason, the base subtype is never allowed for an attribute specified via an aspect_specification on the partial view.}
(6) Modify 3.5(56.4/3):
If a derived type [with no primitive subprograms] inherits a boolean Default_Value aspect, the aspect may be specified to have any value for the derived type.
[Editor's note: This wording is modified further by (10), below.]
Modify 3.6(22.2/3):
If a derived type [with no primitive subprograms] inherits a boolean Default_Component_Value aspect, the aspect may be specified to have any value for the derived type.
(7) Modify B.3(65.1/5):
An Ada enumeration type corresponds to a C enumeration type with corresponding enumeration literals having the same internal codes, provided the internal codes fall within the range of the C int type. [The Ada Boolean type corresponds to the C bool type.]
(8) Modify 4.5.10(34/5):
For a parallel reduction expression, it is a bounded error if the reducer subprogram is not associative. That is, for any arbitrary values of subtype Value_Type A, B, C and a reducer function R, the result of R (A, R (B, C)) should produce a result equal to R (R (A, B), C)){; it is a bounded error if R does not}. The possible consequences are Program_Error, or a result that does not match the equivalent sequential reduction expression due to the order of calls on the reducer subprogram being unspecified in the overall reduction. Analogous rules apply in the case of a reduction procedure.
(9) Modify 13.1(10/5):
{A by-reference primitive is a user-defined primitive subprogram for a type T that has an access result designating type T, or that has a formal parameter that is an access parameter designating type T or is aliased and of type T.} It is illegal to specify a nonconfirming type-related representation aspect for an untagged [by-reference] type T if it is derived from a by-reference type {or inherits one or more by-reference primitives}, or if one or more types have been derived from T prior to the specification of the aspect {and type T is a by-reference type or defines one or more by-reference primitives that are inherited by these descendants}.
Modify AARM 13.1(10.b/5): 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 by-reference primitives is that access parameters, access results, and aliased parameters cannot be converted as part of invoking an inherited subprogram if the representation of the designated types might be different.} 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) Modify 3.5(56.4/3): [including the change from (6), above]
If a derived type [with no primitive subprograms] inherits a boolean Default_Value aspect, the aspect may be specified to have any value for the derived type.{ If a derived type T does not inherit a Default_Value aspect, it shall not specify such an aspect if it inherits a primitive subprogram that has a parameter of type T of mode OUT.
AARM Reason: The second sentence is to avoid violating the rules specified in 6.4.1 about view conversions of OUT parameters with a specified Default_Value aspect.}
(11) Modify 4.3.5(6/5):
The name specified for Empty for an Aggregate aspect shall denote a constant of the container type, or denote [a]{exactly one} function with a result type of the container type that has no parameters, or that has one in parameter of [type Integer]{a signed integer type}.
(12) Modify 9.10.1(26/5):
When the conflict check policy Known_Parallel_Conflict_Checks {or All_Parallel_Conflict_Checks} applies, the implementation may disallow two concurrent actions appearing within parallel constructs if the implementation can prove they will at run-time denote the same object with uses that conflict. Similarly, when the conflict check policy Known_Tasking_Conflict_Checks {or All_Tasking_Conflict_Checks} applies, the implementation may disallow two concurrent actions, at least one of which appears within a task body but not within a parallel construct, if the implementation can prove they will at run-time denote the same object with uses that conflict.
(13) Modify the last portion of 4.2.1(7/5):
... The actual parameter of this notional call is a string_literal {representing a sequence of characters that is the same as the sequence of characters in the original numeric literal, or the sequence represented by the original string} [having the textual representation of the original (numeric or string)] literal.
!discussion
(1) The first paragraph is modeled on that found in 13.13.2(51/3) for stream-oriented attributes. The added sentences are modeled on 13.11(21.5/3) for calls to Allocate.
Note that we don't consistently mention exception propagation in the RM; such wording is not needed since the definition of exception propagation in 11.4 clearly covers that (it's not limited to particular constructs). For example, we have exception propagation wording for calls to Allocator in allocators, but we have no such wording for calls to Deallocation from Unchecked_Deallocation. As such, we only added it in a few cases where it was easy and did not disrupt the flow of the text.
(2) We could try to rewrite the note to make it True. However, this note is in the introductory material for renaming, so it should not be very detailed. Moreover, the original purpose clearly is to note that not all objects can be renamed -- but all objects (and many values as well) CAN be renamed in Ada 202x, so any revised note is not longer serving that purpose. The notion that not all constructs can be used in all possible ways seems fundamental to a programming language, and the RM does not need notes to give out random facts (especially in the general overview material). Thus we recommend deleting this note.
If there is felt to be value in a revised note, the Editor would suggest that such a note would be more appropriate in 8.5.1 (details of object renaming) rather than in the overview material of 8.5.
(3) As noted in the !problem, 7.3.2(5/4) and 7.3.3(4/5) specify a different subtype, so we should make it clear that this rule can be overridden by a more specific rule.
(4) An aggregate is composed of all of the other kinds of things, and might be evaluated piece-meal. As such, it is best to handle them separately.
(5) While there can be no doubt of the intent of an equivalence between specification via an aspect_specification and an attribute_definition_clause, we have been trying to eliminate semantic rules that specifically mention how some aspect/attribute is specified, since those can be misread easily and are always confusing.
The rule of 13.3(6) (which is associated with the description of attribute_definition_clauses) should be moved to 13.1 (which contains rules that apply to all aspects). There are no other rules that apply to all aspects in 13.3; this is an unusual place that even Ada experts have difficulty finding.
The author checked the entire AARM for uses of attribute_definition_clause, and did not find any other rules that needed generalization.
(6) As noted, 13.1(10) does not apply anymore to most derived types, so we do not want these rules enforcing an obsolete restriction.
(7) We don't need to say that C_Bool corresponds to Bool, as that is required by B.3(43/5) - and a requirement is stronger than Implementation Advice.
(8) The least change possible is just to make it clear that the bounded error occurs when the second sentence's requirement is False.
(9) We define the term "by-reference primitives" (meaning those that have anonymous access parameters or results, or aliased parameters) to simplify whatever wording is chosen.
One option is that by-reference primitives "become" abstract when inherited by a derived type with some different representation aspect. However, that is incompatible with generics, since currently all operations are available on a formal derived type inside a generic, even though all operations are effectively inherited.
We also could have required such by-reference primitives to "require overridding". However, the language currently does not require overriding for any tagged type inheritance (meaning additional implementation burden), and this also doesn't solve the problem for generics, since the original operations "re-emerge" in a generic (overridding is purely a visibility effect for untagged types).
Thus, the only reasonable solution is to be to go back to disallowing the specification of a nonconfirming representation aspect if there are any by-reference primitives. We considered folding the by-reference type rules into this rule for a further simplification, but 4.6 (especially 4.6(58.2/4)) assumes that any related by-reference types can be converted without any representation change. Perhaps we could change that, but doing so would cancel out any simplification to 13.1.
(10) We want a Legality Rule as raising Program_Error is likely to have a greater implementation burden than enforcing a Legality Rule, and it could cause a hidden problem in a program that only occurs in unusual cases.
We choose to prevent declaring a problematic type. Other rules (such as making calls on such inherited operations illegal or requiring overriding of the operations) would have a much higher implementation burden, as we're already enforcing similar rules (both this one and 13.1(10/5)).
We only need to disallow adding a Default_Value aspect. The rules in 6.4.1(5.1/5) through 6.4.1(5.4/4) only disallow cases where one type has a Default_Value and the other doesn't, or where they both have it but don't have a common ancestor. Clearly a derived type and its parent have a common ancestor, and clearly you can't get rid of a Default_Value aspect when you have it, so the only issue is adding a Default_Value aspect.
The choosen rule has the advantage that it could be compatibly relaxed in the future (perhaps to "require overriding" of problematic operations), if it proves to be a problem in practice. Other rules would probably require an incompatible change to be made more friendly.
(11) We already have a minor issue if there is a parameterless function and one with a single Integer parameter -- which one is used for Empty? This change thus fixes that bug as well as the one mentioned in the !problem.
(12) It's likely easier for implementers if this permission applies to the All_xxx_Checks as well as Known_xxx_Checks, as the former is then a more pure superset of the latter.
[Editor's note: It is my contention that (assuming the All_xxx_Checks is defined as intended), that this permission can never have an effect for an All_xxx_Checks policy. Any case where later detection (such as in an instance) could happen should have been illegal initially, as All_xxx_Checks is an assume-the-worst rule -- it only allows things that are certain to not conflict. So I don't see how the permission could possibly matter, since anything that the permission could detect was already illegal. What might help here would be the reverse permission -- that is, allowing not rejecting code that can be proven safe in the All_xxx_Checks policies. But that clearly is a bridge too far at this late date - whether the effect on portability is acceptable would need lots of community input.]
(13) Indeed, the intent is that no enclosing quotes are passed to these routines. That needed to be made explicit.
!corrigendum 3.5(56.4/3)
Replace the paragraph:
If a derived type with no primitive subprograms inherits a boolean Default_Value aspect, the aspect may be specified to have any value for the derived type.
by:
If a derived type inherits a boolean Default_Value aspect, the aspect may be specified to have any value for the derived type. If a derived type T does not inherit a Default_Value aspect, it shall not specify such an aspect if it inherits a primitive subprogram that has a parameter of type T of mode out.
!corrigendum 3.6(22.2/3)
Replace the paragraph:
If a derived type with no primitive subprograms inherits a boolean Default_Component_Value aspect, the aspect may be specified to have any value for the derived type.
by:
If a derived type inherits a boolean Default_Component_Value aspect, the aspect may be specified to have any value for the derived type.
!corrigendum 4.2.1(0)
Insert new clause:
See the conflict file for the changes.
!corrigendum 4.3.5(0)
Insert new clause:
See the conflict file for the changes.
!corrigendum 4.5.10(0)
Insert new clause:
See the conflict file for the changes.
!corrigendum 4.10(0)
Insert new clause:
See the conflict file for the changes.
!corrigendum 8.5(5)
Delete the paragraph:
10 A task or protected object that is declared by an explicit object_declaration can be renamed as an object. However, a single task or protected object cannot be renamed since the corresponding type is anonymous (meaning it has no nameable subtypes). For similar reasons, an object of an anonymous array or access type cannot be renamed.
!corrigendum 8.6(17.1/5)
Replace the paragraph:
Within an aspect_specification for a type or subtype, the current instance represents a value of the type; it is not an object. The nominal subtype of this value is given by the subtype itself (the first subtype in the case of a type_declaration), prior to applying any predicate specified directly on the type or subtype. If the type or subtype is by-reference, the associated object of the value is the object associated (see 6.2) with the evaluation of the usage name.
by:
Within an aspect_specification for a type or subtype, the current instance represents a value of the type; it is not an object. Unless otherwise specified, the nominal subtype of this value is given by the subtype itself (the first subtype in the case of a type_declaration), prior to applying any predicate specified directly on the type or subtype. If the type or subtype is by-reference, the associated object of the value is the object associated (see 6.2) with the evaluation of the usage name.
!corrigendum 9.10.1(0)
Insert new clause:
See the conflict file for the changes.
!corrigendum 13.1(10/4)
Replace the paragraph:
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.
by:
A by-reference primitive is a user-defined primitive subprogram for a type T that has an access result designating type T, or that has a formal parameter that is an access parameter designating type T or is aliased and of type T. It is illegal to specify a nonconfirming type-related representation aspect for an untagged type T if it is derived from a by-reference type or inherits one or more by-reference primitives, or if one or more types have been derived from T prior to the specification of the aspect and type T is a by-reference type or defines one or more by-reference primitives that are inherited by these descendants.
!corrigendum 13.1(13.1/3)
Insert after the paragraph:
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.
the new paragraph:
When specifying an aspect that denotes a subprogram, the profile of the subprogram shall be mode conformant with the one required for the aspect, and the convention shall be Ada. Additional requirements are defined for particular aspects.
!corrigendum 13.1.1(21/3)
Replace the paragraph:
by:
!corrigendum 13.1.1(22/3)
Replace the paragraph:
by:
!corrigendum 13.3(6)
Delete the paragraph:
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.
!corrigendum 13.13.2(51/3)
Replace the paragraph:
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.
by:
For an attribute_definition_clause or aspect_specification 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.
!corrigendum B.3(65.1/5)
Replace the paragraph:
by:
!ASIS
No ASIS effect.
!ACATS test
No ACATS Tests needed.
!appendix

From: Tucker Taft
Sent: Thursday, March 18, 2021  11:07 AM

Here is a comment that might best be considered as a "WG9-stage" comment 
on the latest draft (#29.3) of the Ada 202X RM: [It was WG 9 issue #8, see
below - Editor.]

In RM 13.1.1(19/3-22/3) we have:

Depending on which aspect is identified by the aspect_mark, an 
aspect_definition specifies:
* a name that denotes a subprogram, object, or other kind of entity;
* 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
* an identifier specific to the aspect.

This is relatively old wording, and doesn't mention "aggregate" which is of 
course a kind of expression, but in newer wording is called out separately, 
and it is certainly misleading to talk about it being evaluated to produce 
a "single value."

I would suggest we augment the above as follows:

Depending on which aspect is identified by the aspect_mark, an 
aspect_definition specifies:
* a name that denotes a subprogram, object, or other kind of entity;
* an expression{ (other than an aggregate)}, 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]
* an identifier specific to the aspect{; or
* an aggregate, which is positional or named, and is composed of elements of 
  any of these four kinds of constructs}.

****************************************************************

From: Randy Brukardt
Sent: Saturday, March 20, 2021  2:20 AM

I agree this should be fixed as you suggest. It looks like an oversight to me; 
we made a similar fix to 13.1.1(5 through 11) and I'd guess we missed that 
there was a second place that needed a fix.

****************************************************************

From: Tucker Taft
Sent: Thursday, March 18, 2021  11:31 AM

Randy suggested I bring this comment to the ARG as a WG9-stage comment.


We have added C_bool to Interfaces.C, which is defined to be equivalent to C's
"bool" (or  "_Bool").  It now seems misleading to say that Ada's 
Standard.Boolean type "corresponds" to the C bool type.  The point of 
introducing C_bool was so that you could be certain that you had a type 
compatible with C, and there was no guarantee that, for example, a record 
component of type Standard.Boolean would match a C struct component of type 
"bool."

The current state of RM B.3(65.1/5) is

* An Ada enumeration type corresponds to a C enumeration type with 
  corresponding enumeration literals having the same internal codes,
  provided the internal codes fall within the range of the C int type.
  The Ada Boolean type corresponds to the C bool type.

That last sentence was not present when this paragraph was added, which 
originated from AI12-0135-1.  The last sentence came from AI12-0411-1, which
defined Interfaces.C.C_bool.  I admit I wrote the original version of 
AI12-041101, but now that last sentence seems to miss the whole point of the
addition of C_bool, namely, that there is no requirement that the Ada Boolean
type itself corresponds to the C bool type.  It would make more sense to say 
something like the following, I believe:

* An Ada enumeration type corresponds to a C enumeration type with 
  corresponding enumeration literals having the same internal codes, 
  provided the internal codes fall within the range of the C int type.
  Interfaces.C.C_bool, a boolean type derived from the Standard.Boolean 
  type, corresponds to the C bool type.

We could also mark this new last sentence as "redundant" (i.e., inside [ ... ] 
in the AARM) as it is implied by other wording now in the draft RM that says 
that C_bool corresponds to C's bool, plus the declaration of C_bool to be 
derived from Standard.Boolean.

****************************************************************

From: Jean-Pierre Rosen
Sent: Thursday, March 18, 2021  11:43 AM

>     * An Ada enumeration type corresponds to a C enumeration type with
>     corresponding enumeration literals having the same internal codes,
>     provided the internal codes fall within the range of the C int type.
>     Interfaces.C.C_bool, a boolean type derived from the
>     Standard.Boolean type, corresponds to the C bool type.
> 
Does it correspond to this sea bull?
https://www.alamy.com/stock-photo-greenland-sea-norway-svalbard-archipelago-spitsbergen-walrus-odobenus-55591858.html

****************************************************************

From: Tucker Taft
Sent: Thursday, March 18, 2021  12:15 PM

Of course the Sea Bull Walrus would let us know that...

   The time has come,' the Walrus said,
      To talk of many things:
   Of shoes  and ships  and sealing-wax 
      Of cabbages  and kings 
   And why the sea is boiling hot 
      And whether pigs have wings.'
   And whether bool is C_Bool,
      Or Standard dot Booling!

****************************************************************

From: Randy Brukardt
Sent: Saturday, March 20, 2021  2:18 AM

... 
> I admit I wrote the original version of AI12-041101, but now that last 
> sentence seems to miss the whole point of the addition of C_bool, 
> namely, that there is no requirement that the Ada Boolean type itself 
> corresponds to the C bool type.

I certainly agree with this, but I thought that we had that discussion at the 
time and I lost (and the sentence remained). I certainly thought the intent 
was as written -- this is Implementation Advice anyway, no one has to follow
it.

>It would make more sense to say something like the following, I believe:

>* An Ada enumeration type corresponds to a C enumeration type with
>  corresponding enumeration literals having the same internal codes,  
>  provided the internal codes fall within the range of the C int type.
>  Interfaces.C.C_bool, a boolean type derived from the Standard.Boolean  
>  type, corresponds to the C bool type.

I don't see any reason to mention Interfaces.C.C_bool here. We don't mention 
any of the other Interfaces.C types in this Implementation Advice, because 
they are already *normatively* corresponding (in B.3(43/5)). It makes no sense
to repeat that in IA - IA is weaker, after all.

>We could also mark this new last sentence as "redundant" (i.e., inside 
>[ ... ] in the AARM) as it is implied by other wording now in the draft  
>RM that says that C_bool corresponds to C's bool, plus the declaration  
>of C_bool to be derived from Standard.Boolean.

I see no reason to mention it at all, as stated above. I thought people wanted 
to encourage a correspondence between Boolean and the C bool type, otherwise 
it should never have been there in the first place.

****************************************************************

From: Tucker Taft
Sent: Saturday, March 20, 2021  5:21 PM

I am happy to drop the problematic sentence completely.  I had the sense that 
Randy or someone else thought the sentence should be preserved, but if so, it 
should not imply a direct correspondence between Ada Boolean and C bool, but 
rather indicate the C_bool type, derived from Boolean, is required to 
correspond.  But that is definitely redundant with the update made to 
B.3(43/5), so happy to leave it out completely.

****************************************************************

From the WG 9 review, issue #2.

Stream attributes define the subtype of the parameter of the associated
subprograms with 13.13.2(51/3). We don't have any similar rule for Put_Image
in 4.10. The definition of Put_Image seems to suggest that the parameter is
of type T, but types do not have names in Ada -- one always has to specify a
subtype.

Tucker also notes that we don't mention that the implicit calls of Put_Image
propagate any exceptions (including those caused by a subtype check
failure); we doubt anyone would expect anything else, but it usually is
explicitly mentioned in the RM.

****************************************************************

From the WG 9 review, issue #151.

8.5(5): This note says that an object of an anonymous access type cannot be 
renamed. However, it seems to me that the second alternative in RM 8.5.1 (1/5),
the "access_definition" case, does allow such a renaming. Similarly, RM 8.5 (5)
says that a single task or protected object cannot be renamed since the 
corresponding type is anonymous, but as we can now omit the subtype_mark from
the object_renaming_declaration, it seems that such entities can be renamed. 
Either I am wrong, or the statements in RM 8.5 (5) are wrong.

Tucker Taft replied:

Another good catch! I would suggest we change the note to say:

    10 A task or protected object that is declared by an explicit 
    object_declaration can be renamed as an object. However, a single task
    or protected object [cannot]{can} be renamed {only using the form of 
    renaming that omits specifying the subtype} [since the corresponding type
    is anonymous (meaning it has no nameable subtypes). For similar reasons, 
    an object of an anonymous array or access type cannot be renamed].

This is a bit informal (i.e. "specifying the subtype" is not a defined 
technical notion) but that is generally fine for a "Note".

Your editor replied:

I wonder if this note retains enough value to bother with it at all. The 
original purpose was to say that not all objects can be renamed, but that is
False with Ada 202x, and indeed one now can rename most values as well. Saying
that something can only be renamed with the most simple (and likely common) 
form of renaming is hardly interesting. We don't need notes to tell people 
random facts about the language.

I'll write up deleting the note in AI12-0427-1 (the fixup AI), and we can 
decide if that is acceptable or not in the ARG.

****************************************************************

From the WG 9 review, issue #152.

The nominal (sub)type specified in 8.6(17.1/5) for the "current instance"
value seems to be overridden in RM 7.3.2 (5/4) for the aspect
Type_Invariant'Class, and in RM 7.3.3 (4/5) for the aspect 
Default_Initial_Condition, where different types ("NT") are specified for 
the current instance. Perhaps this apparent contradiction should be addressed
in some way, by a note or by an exception phrase in the general rule.

Tucker Taft replied:

Might want to add simply "Unless otherwise specified in this document, ...".

****************************************************************

From the WG 9 review, issue #8.

In RM 13.1.1(19/3-22/3) we have:

Depending on which aspect is identified by the aspect_mark, an
aspect_definition specifies:

  * a name that denotes a subprogram, object, or other kind of entity;
  * 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
  * an identifier specific to the aspect.

This is relatively old wording, and doesn't mention "aggregate" which is of
course a kind of expression, but in newer wording is called out separately,
and it is certainly misleading to talk about it being evaluated to produce a
"single value."

Suggested fix:

We should augment the above as follows:

Depending on which aspect is identified by the aspect_mark, an
aspect_definition specifies:

  * a name that denotes a subprogram, object, or other kind of entity;
  * an expression{ (other than an aggregate)}, 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]
  * an identifier specific to the aspect{; or
  * an aggregate, which is positional or named, and is composed of elements of
    any of these four kinds of constructs}.

****************************************************************

From the WG 9 review, issue #3.

The listed paragraphs give requirements on subprograms specified for
attributes (aspects) via an attribute_definition_clause. There is no rule
that does that for aspects specified via aspect_specifications.

There is a usual equivalence of aspects that can be specified via
aspect_specifications, and the Dewar rule applies here -- it would be highly
unusual for these rules to act differently than many others.

However, we have been trying to eliminate semantic rules that specifically
mention how some aspect/attribute is specified, since those can be misread
easily and are always confusing. So we believe these paragraphs should be
rewritten.

Note that if we do that for 13.3(6), it should be moved somewhere more
general (probably 13.1) as it currently is part of rules that only apply to
attribute_definition_clauses. (A reason this change should be made, IMHO -
RLB) Even language lawyers (for example, Steve Baird) have had difficulty
locating this rule when wondering what rules apply to a particular aspect.

****************************************************************

From the WG 9 review, issue #4.

3.5(56.4/3) says:

If a derived type with no primitive subprograms inherits a boolean
Default_Value aspect, the aspect may be specified to have any value for the
derived type.

Tucker tells me that the "with no primitive subprograms" was included to
ensure that we didn't override 13.1(10) with this rule. However, Ada 202x
removes the bulk of 13.1(10) (which mostly was intended to avoid expensive
implicit conversions -- but the effect was to prevent programmers from
writing derived types that they needed even if the expensive conversion was
not a problem). This means this rule as written is a wart, as it seems to
prevent non-confirming Default_Value aspects in the case of a type with
primitive subprograms.

3.6(22.2/3) has similar wording.

Suggested fix: drop the words "with no primitive subprograms" from both of
these rules.

****************************************************************

From the WG 9 review, issue #9.

[This is just a repeat of the ARG thread saved above, starting with a
message from Tucker Taft, Thursday, March 18, 2021  11:31 AM - Editor.]

****************************************************************

From the WG 9 review, issue #16.

In 4.5.10 (34/5) we have
"For a parallel reduction expression, it is a bounded error if the reducer 
subprogram is not associative. That is, for any arbitrary values of subtype 
Value_Type A, B, C and a reducer function R, the result of R (A, R(B, C)) 
should produce a result equal to R (R (A, B), C)). The possible consequences
are Program_Error, or a result that does not match the equivalent sequential
reduction expression due to the order of calls on the reducer subprogram 
being unspecified in the overall reduction. Analogous rules apply in the 
case of a reduction procedure."

The second sentence is misleading in that it is explaining what associative 
means while the first sentence talks about being not associative. Maybe 
better: "For any arbitrary values of subtype Value_Type A, B, C, an 
associative reducer function R should guarantee that the result 
of R (A, R(B, C)) is equal to R (R (A, B), C))."

In addition, it could be mentioned that addition and multiplication of 
floating point numbers are prominent examples of not associative operations. 
A fact that many programmers are not aware of.

****************************************************************

Editor's reply to the previous item:

We had a very hard time agreeing on wording for this one, so I would want to 
change it as little as possible. As such, I suggest adding "; it is a bounded
error if R does not" to the end of the second sentence to provide the 
clarification you are asking for, This was added to the fixups AI 
(AI12-0427-1).

As far as the second suggestion is concerned, we don't want "fun facts" in the 
normative rules of the Standard. I suppose it could be mentioned in the AARM 
or a user note, but that seems to be of less value since it would be separated
from the reason it matters. So I'm not going to do anything with this second 
point.

****************************************************************

From the WG 9 review, issue #114.

We have relaxed the rules relating to specifying type-related representation 
aspects when there are primitives that might be inherited by derived types 
with a different representation. However, we did not take into account that 
some parameters are necessarily passed by reference, even if the type itself
is not a by-reference type. Such parameters cannot easily be converted 
automatically when calling an inherited subprogram. One option is for such 
"by-reference primitives" to "become" abstract when inherited by a derived 
type with some different representation aspect. However, that is incompatible
with generics, since currently all operations are available on a formal
derived type inside a generic, even though all operations are effectively 
inherited. After discussion, the simplest solution seems to be to go back to 
disallowing the specification of a nonconfirming representation aspect if 
there are any "by-reference primitives." Hence, I would suggest we modify 
13.1(10/5) as follows:

Modify RM 13.1(10/5):

    {A by-reference primitive is a user-defined primitive subprogram for a 
    type T that has an access result designating type T, or that has a formal
    parameter that is an access parameter designating type T or is aliased and
    of type T.} It is illegal to specify a nonconfirming type-related 
    representation aspect for an untagged [by-reference] type T if it is
    derived from a by-reference type {or inherits one or more by-reference
    primitives}, or if one or more types have been derived from T prior to 
    the specification of the aspect {and type T is a by-reference type or 
    defines one or more by-reference primitives that are inherited by these 
    descendants}.

    {AARM Reason: Access parameters, access results, and aliased parameters 
    cannot be converted as part of invoking an inherited subprogram if the 
    representation of the designated types might be different.}

We could simplify this further, which would effectively relax the existing 
rules for a by-reference type that has no primitives, to the following:

    {A by-reference primitive is a user-defined primitive subprogram for a 
    type T, if T is a by-reference type, or if the primitive has an access 
    result designating type T, or has a formal parameter that is an access 
    parameter designating type T or is aliased and of type T.} It is illegal
    to specify a nonconfirming type-related representation aspect for an 
    untagged [by-reference] type T if it [is derived from a by-reference 
    type] {inherits one or more by-reference primitives}, or if one or more
    types have been derived from T prior to the specification of the aspect
    {and type T defines one or more by-reference primitives that are 
    inherited by these descendants}.

In the spirit of removing unnecessary restrictions, this simpler rule might be 
preferred.

[Later message]

Randy noted that we should probably not change the rules on by-reference 
types, since in 4.6(58.2/4) we assume all by-reference types can be converted
without representation change. So that implies we should retain the 
distinction as suggested in the first alternative proposed above.

****************************************************************

From the WG 9 review, issue #5.

[From Randy Brukardt:]

Paragraphs 6.4.1(5.1/5) through 6.4.1(5.4/4) define a Legality check for
some scalar view conversions passed to OUT mode parameters.

When a type is derived, any inherited subprograms are called with the actual
parameters of the new type view converted to the parent type. This can cause
an anomaly, in that an explicit call would be illegal while calling an
inherited routine (which makes the same call implicitly) is legal.

Tucker notes that 6.4.1(15.1/5) says that this view conversion raises
Program_Error. Therefore, there is no language bug in that code that does
not follow the principles cannot be executed. OTOH, the rule Tucker refers
to was only intended to be used in generic bodies (and there is an AARM note
to that effect). So implementers and users alike are likely to be confused.

Moreover, we have a Language Design Principle (admittedly, not always
followed) that a construct which will always raise an exception should be
detected at compile-time. So it seems that a Legality Rule is missing here.

Suggested fix: Add a Legality Rule to reject any call on an inherited
routine with an out parameter where the implied view conversion would be
illegal.

Example: Here is an example of this situation:

package P1 is
   type Moddy is mod 2**16;

   procedure Convert (Ival : in Integer; Mval : out Moddy);

end P1;

with P1;
package P2 is
   type IModdy is new P1.Moddy
      with Default_Value => 65535; -- [A]
   -- Convert inherited here.
end P2;

with P1, P2;
procedure Tester is
   V : P2.IModdy;
begin
   P1.Convert (10, P1.Moddy(V)); -- [B]
   P2.Convert (10, V); -- [C]
end Tester;

[C] is implemented as [B] -- 3.4(27/2).

But [B] is illegal by 6.4.1(5.1-4/5) -- the operand type has a Default_Value
and the target type does not.

The equivalence is only for Dynamic Semantics, so the Legality Rule does not
apply. But 6.4.1(15.1/5) does apply, so [C] is required to raise Program_Error.

[From Tucker Taft:]

It would perhaps be better to require such primitives to be overridden, since 
having a primitive that is illegal to call might have cascading weird effects.
On the other hand, this only comes up with non-tagged types, so there is no 
dispatching to worry about, and ancestor primitives re-emerge in a generic, so
perhaps I am merely sowing Fear, Uncertainty, and Doubt.

It still seems friendlier, though, to require overriding. You could of course 
override with a subprogram that always raised Program_Error if so desired, but
at least you are being explicit about it.

[From Randy Brukardt:]

I didn't suggest requiring overriding, as that is something that currently 
happens only for tagged types. As such, adding it for an unlikely case for 
untagged types could be a substantial implementation burden. (If tagged 
derivation is separately implemented from untagged derivation, then one would 
need to implement a new mechanism for untagged types.) I do agree it would be 
friendlier to a user, but only in unusual circumstances (and it would be 
incompatible with Ada 2012 in those circumstances).

I don't think there would be any "cascading weird effects", as you note that 
there isn't any effect in generics.

[From Tucker Taft:]

An alternative would be to add yet another restriction on applying a 
representation clause to a type with primitives. It used to be completely
illegal, and now we are beginning to find out why... ;-) But at least we are
certain we are keeping all of the "hair" in the same place, namely, in 
limiting how far we loosen this rule. I'll see if I can come up with wording 
for the two different approaches -- disallowing the call, or disallowing the 
representation change -- and I'll add it as another comment.

[From Randy Brukardt:]

It would seem weird to add something to 13.1(10/5) about a specific aspect 
used with a specific kind of parameter - it doesn't seem general enough. But
I suppose we could have a wart rule in 3.5 specifically to disallow such 
Default_Values. That seems less friendly than just disallowing uses of such
inherited routines, but it's probably not a huge issue either way.

[From Steve Baird:]

Given our recent discussion about inherited subprograms with
aliased untagged parameters, it sounds like we are already planning
on adding new cases to 13.1(10) for other reasons. So I would prefer
to address this problem there.

[From Tucker Taft:]

We are simplifying the current rule in 3.5, so perhaps we could make it more 
complex again:

    If a derived type [with no primitive subprograms] inherits a boolean 
    Default_Value aspect, the aspect may be specified to have any value for 
    the derived type. {If a derived type T does not inherit a Default_Value 
    aspect, it shall not specify such an aspect if it inherits a primitive 
    subprogram that has a parameter of type T of mode OUT.

    AARM Reason: This is to avoid violating the rules specified in 6.4.1 about 
    view conversions of OUT parameters with a specified Default_Value aspect.}

The rules in 6.4.1(5.1/5) through 6.4.1(5.4/4) only disallow cases where one 
type has the Default_Value and the other doesn't, or where they both have it
but don't have a common ancestor. Clearly a derived type and its parent have 
a common ancestor, and clearly you can't get rid of a Default_Value aspect 
when you have it, so the only issue is adding a Default_Value aspect.

[From Randy Brukardt:]

This rule has the advantage that it could be compatibly relaxed in the future 
(perhaps to "require overriding"), if it proves to be a problem. Other rules 
would probably require an incompatible change to be made more friendly.

****************************************************************

From the WG 9 review, issue #116.

4.2.1(7/5) says:

    ... The actual parameter of this notional call is a string_literal having 
    the textual representation of the original (numeric or string) literal.

Does the textual representation of a string literal include the quotes on 
either end? And what about doubled quotation marks occurring in the middle?
Based on the example of Roman_Number, I would guess the answer is the 
enclosing quotes are removed, and a doubled quotation mark becomes a single 
quotation mark, but that is not clear from this rule. I would suggest the 
following:

    ... The actual parameter of this notional call is a string_literal having 
    the textual representation of the original (numeric or string) literal{; 
    in the case of a string literal, the enclosing quotation marks from the 
    original textual representation are not included, and doubled quotation 
    marks in the textual representation are represented by a single quotation
    mark in the actual parameter}.

---

On further thought, the string literal case to some extent makes more sense 
than the numeric literal case. How can a string literal have the same textual
representation as a numeric literal? At a minimum it needs enclosing quotation
marks. I think part of the confusion here is that we are swinging between a 
syntactic view and a semantic view, while not always being clear which one we 
mean at any given time. So perhaps this should be changed as follows:

    ... The actual parameter of this notional call is a string_literal 
    {representing a sequence of characters that is the same as the sequence 
    of characters in the original numeric literal, or the sequence represented 
    by the original string} [having the textual representation of the original 
    (numeric or string)] literal.

****************************************************************

Questions? Ask the ACAA Technical Agent