CVS difference for ai05s/ai05-0153-3.txt

Differences between 1.16 and version 1.17
Log of other versions for file ai05s/ai05-0153-3.txt

--- ai05s/ai05-0153-3.txt	2011/04/20 20:18:48	1.16
+++ ai05s/ai05-0153-3.txt	2011/05/10 04:57:53	1.17
@@ -1,4 +1,19 @@
-!standard  3.2.4(0)                                11-04-20    AI05-0153-3/09
+!standard  3.2.4(0)                                11-05-06    AI05-0153-3/10
+!standard  3.8.1(5)
+!standard  3.8.1(8)
+!standard  3.8.1(11)
+!standard  3.8.1(15)
+!standard  4.3.3(17)
+!standard  4.5.2(29)
+!standard  4.5.2(30/2)
+!standard  4.6(51/2)
+!standard  4.9(26/2)
+!standard  4.9.1(2/2)
+!standard  4.9.1(4)
+!standard  5.4(5)
+!standard  5.4(7)
+!standard  6.4.1(13)
+!standard  13.9.2(3)
 !class Amendment 09-05-27
 !status Amendment 2012 11-03-04
 !status ARG Approved  7-0-1  11-02-18
@@ -194,7 +209,8 @@
 or Range shall not denote a scalar subtype to which predicate specifications
 apply.
 
-The discrete_subtype_definition of a loop_parameter_specification shall not
+The discrete_subtype_definition of a loop_parameter_specification or a
+discrete_choice of a named_array_aggregate shall not
 denote a subtype to which Dynamic_Predicate specifications apply.
 
 
@@ -210,9 +226,10 @@
   predicate of the subtype of the actual is evaluated, and a check is made that
   the predicate is True. For an object created by an object_declaration with no
   explicit initialization expression, or by an uninitialized allocator, if any
-  subcomponents have explicit default values, the predicate of the nominal
-  subtype is evaluated, and a check is made that the predicate is True.
-  Assertions.Assertion_Error is raised if any of these checks fail.
+  subcomponents have default_expressions, the predicate of the nominal
+  subtype of the created object is evaluated, and a check is
+  made that the predicate is True. Assertions.Assertion_Error is raised if
+  any of these checks fail.
 
 AARM Ramification: Predicates are not evaluated at the point of the [sub]type
 declaration.
@@ -242,10 +259,13 @@
 
 [End of 3.2.4.]
 
-3.8.1(5,11) says:
+3.8.1(5,8,11,15) says:
 
 5     discrete_choice ::= expression | discrete_range | others
 
+8   The expressions and discrete_ranges given as discrete_choices in a variant_part shall
+    be static. ...
+
 11      * A discrete_choice that is a discrete_range covers all values
       (possibly none) that belong to the range.
 
@@ -253,15 +273,17 @@
       each non-others discrete_choice shall cover only values in that subtype,
       and each value of that subtype shall be covered by some discrete_-
       choice [(either explicitly or by others)];
+
+Modify 3.8.1(5,8,11,15) so the full coverage rules take predicates
+into account. This applies only in the static case:
+
+5     discrete_choice ::= choice_expression | *discrete_*subtype_indication | range | others
+
+[Note: AI05-0158-1 changes "expression" to "choice_expression". We are no longer
+using discrete_range here, because it's not necessarily a contiguous range.]
 
-Modify 3.8.1(5,11,15) so the full coverage rules take predicates
-into account. This applies only in the static case (by existing
-wording):
-
-5     discrete_choice ::= choice_expression | discrete_subtype_indication | range | others
-[Note: AI-158 changes "expression" to "choice_expression".
-We are no longer using discrete_range here, because it's not
-necessarily a contiguous range.]
+8   The choice_expressions, subtype_indications, and ranges given as discrete_choices
+    in a variant_part shall be static. ...
 
 11      * A discrete_choice that is a subtype_indication covers all values
       (possibly none) that belong to the subtype.
@@ -275,12 +297,24 @@
       and each value of that subtype {that satisfies the predicate}
       shall be covered by some discrete_choice [(either explicitly or by others)];
 
-Modify 4.5.2(29) so membership tests take the predicate into account:
+Modify 4.3.3(17) to take the syntax change above into account:
 
-The tested type is scalar, and the value of the simple_expression belongs to the
-given range, or the range of the named subtype {and the predicate of the named
-subtype evaluates to True}; or
+"...that is a {subtype_indication or range}[discrete_range] that defines a nonstatic
+or null range..."
 
+Replace 4.5.2(29) so membership tests take the predicate
+into account (this includes the modifications of AI05-0158-1):
+
+The membership_choice is a range and the value of the
+simple_expression belongs to the given range.
+
+[Note: We don't have to mention that the type is scalar here because there aren't any
+non-scalar ranges.]
+
+The membership_choice is a subtype_mark, the tested type is scalar, the value of
+the simple_expression belongs to the range of the named subtype, and the predicate
+of the named subtype evaluates to True.
+
 Modify AARM-4.5.2(29.a):
 
           Ramification: The scalar membership test only does a range check {and
@@ -310,7 +344,7 @@
 Modify 4.9.1(2/2), so static matching takes predicates into account:
 
   A subtype statically matches another subtype of the same type if they have
-  statically matching constraints, {all predicate specification that apply to
+  statically matching constraints, {all predicate specifications that apply to
   them come from the same declarations, }and, for access subtypes, either both
   or neither exclude null. ...
 
@@ -328,7 +362,7 @@
   {Two statically matching subtypes are statically compatible with each other.
   In addition, a subtype S1 is statically compatible with a subtype S2 if:
 
-      - S1's constraint is statically compatible with S2, and
+      - the constraint of S1 is statically compatible with S2, and
 
       - if S2 excludes null, so does S1, and
 
@@ -339,6 +373,11 @@
         - both subtypes are static, and every value that obeys S1's
           predicate also obeys S2's predicate.}
 
+Modify 5.4(5), so that the removal of discrete_ranges from discrete_choice
+is reflected:
+
+5   The choice_expressions, subtype_indications, and ranges given as discrete_choices
+    in a case_statement shall be static. ...
 
 Modify 5.4(7/3), so the full coverage rules for case statements
 take predicates into account:
@@ -347,7 +386,7 @@
       type_conversion, a qualified_expression, or a function_call)] having a
       static and constrained nominal subtype, then each non-others
       discrete_choice shall cover only values in that subtype
-      {that satisfy the predicate}{that satisfy the predicate}, and each value
+      {that satisfy the predicate}, and each value
       of that subtype {that satisfies the predicate}
       shall be covered by some discrete_choice [(either
       explicitly or by others)].
@@ -356,7 +395,7 @@
 
 For an access type, the formal parameter is initialized from the value of the
 actual, without checking that the value satisfies any
-constraint{, the predicate,} or any null exclusion;
+constraint{, any predicate,} or any null exclusion;
 
 Modify 13.9.2(3), so 'Valid takes predicates into account:
 
@@ -923,9 +962,336 @@
 Land_Airplane takes a parameter of subtype Airplane_That_Is_Ready_To_Land, which
 is a subtype of Airplane.
 
+
+!corrigendum 3.2.4(0)
+
+@dinsc
+The language-defined @i<predicate aspects> Static_Predicate and Dynamic_Predicate
+may be used to define properties of subtypes. A @i<predicate specification> is an
+@fa<aspect_specification> for one of the two predicate aspects.
+
+@s8<@i<Name Resolution Rules>>
+
+The expected type for a predicate aspect @fa<expression> is any boolean type.
+
+@s8<@i<Static Semantics>>
+
+A predicate specification may be given on a @fa<type_declaration> or a
+@fa<subtype_declaration>, and applies to the declared subtype. In addition, predicate
+specifications apply to certain other subtypes:
+
+@xbullet<For a (first) subtype defined by a derived type declaration,
+the predicates of the parent subtype and the progenitor subtypes apply.>
+
+@xbullet<For a subtype created by a @fa<subtype_indication>, the
+predicate of the subtype denoted by the @fa<subtype_mark> applies.>
+
+The @i<predicate> of a subtype consists of all predicate specifications that
+apply, and-ed together; if no predicate specifications apply, the predicate is
+True (in particular, the predicate of a base subtype is True).
+
+@s8<@i<Legality Rules>>
+
+The @fa<expression> of a Static_Predicate specification shall be @i<predicate-static>;
+that is, one of the following:
+
+@xbullet<a static expression that does not raise any exception;>
+
+@xbullet<a membership test whose @fa<simple_expression> is the current instance,
+and whose @fa<membership_choice_list> meets the requirements for a static
+membership test (see 4.9);>
+
+@xbullet<a @fa<case_expression> whose @i<selecting_>@fa<expression> is the
+current instance, and whose @i<dependent_>@fa<expression>s are static expressions;>
 
---!corrigendum 3.2.2(2)
+@xbullet<a call to a predefined equality or ordering operator, where one operand
+is the current instance, and the other is a static expression;>
 
+@xbullet<a call to a predefined boolean logical operator, where both operands
+are predicate-static; or>
+
+@xbullet<a parenthesized predicate-static @fa<expression>.>
+
+An index subtype, @fa<discrete_range> of an @fa<index_constraint> or @fa<slice>,
+or a @fa<discrete_subtype_definition> of a @fa<constrained_array_definition>,
+@fa<entry_declaration>, or @fa<entry_index_specification> shall not denote a
+subtype to which predicate specifications apply.
+
+The @fa<prefix> of an @fa<attribute_reference> whose @fa<attribute_designator> is
+First, Last, or Range shall not denote a scalar subtype to which predicate
+specifications apply.
+
+The @fa<discrete_subtype_definition> of a @fa<loop_parameter_specification>
+or a @fa<discrete_choice> of a @fa<named_array_aggregate> shall not denote a subtype
+to which Dynamic_Predicate specifications apply.
+
+
+@s8<@i<Dynamic Semantics>>
+
+If the Assertion_Policy (see 11.4.2) in effect is Check, then:
+
+@xindent<On every subtype conversion, the predicate of the target subtype is
+evaluated, and a check is made that the predicate is True. This includes all
+parameter passing, except for certain parameters passed by reference, which
+are covered by the following rule: After normal completion and leaving of a
+subprogram, for each @b<in out> or @b<out> parameter that is passed by reference, the
+predicate of the subtype of the actual is evaluated, and a check is made that
+the predicate is True. For an object created by an @fa<object_declaration> with no
+explicit initialization @fa<expression>, or by an uninitialized @fa<allocator>,
+if any subcomponents have @fa<default_expression>s, the predicate of
+the nominal subtype of the created object is evaluated, and a
+check is made that the predicate is True. Assertions.Assertion_Error is raised
+if any of these checks fail.>
+
+If any of the above Legality Rules is violated in an instance of a generic
+unit, Program_Error is raised.
+In addition to the places where Legality Rules normally apply (see
+12.3), this rule applies also in the private part of an instance of a generic
+unit.
+
+@xindent<@s9<NOTES@hr
+5  A predicate specification does not cause a subtype to be considered
+constrained.>>
+
+@xindent<@s9<6  A Static_Predicate, like a constraint, always remains True for all
+objects of the subtype, except in the case of uninitialized variables and
+other invalid values. A Dynamic_Predicate, on the other hand, is checked as
+specified above, but can become False at other times. For example, the
+predicate of a record is not checked when a subcomponent is modified.>>
+
+!corrigendum 3.8.1(5)
+
+@drepl
+@xcode<@fa<discrete_choice ::= expression | discrete_range | >@ft<@b<others>>>
+@dby
+@xcode<@fa<discrete_choice ::= choice_expression | >@ft<@i<discrete_>>@fa<subtype_indication | range | >@ft<@b<others>>>
+
+!corrigendum 3.8.1(8)
+
+@drepl
+The @fa<expression>s and @fa<discrete_range>s given as @fa<discrete_choice>s in a
+@fa<variant_part> shall be static. The @fa<discrete_choice> @b<others> shall appear
+alone in a @fa<discrete_choice_list>, and such a @fa<discrete_choice_list>, if it
+appears, shall be the last one in the enclosing construct.
+@dby
+The @fa<choice_expression>s, @fa<subtype_indication>s, and @fa<range>s given as
+@fa<discrete_choice>s in a
+@fa<variant_part> shall be static. The @fa<discrete_choice> @b<others> shall appear
+alone in a @fa<discrete_choice_list>, and such a @fa<discrete_choice_list>, if it
+appears, shall be the last one in the enclosing construct.
+
+!corrigendum 3.8.1(11)
+
+@drepl
+@xbullet<A @fa<discrete_choice> that is a @fa<discrete_range> covers all values
+(possibly none) that belong to the range.>
+@dby
+@xbullet<A @fa<discrete_choice> that is a @fa<subtype_indication> covers all values
+(possibly none) that belong to the subtype.>
+
+@xbullet<A @fa<discrete_choice> that is a @fa<range> covers all values
+(possibly none) that belong to the range.>
+
+!corrigendum 3.8.1(15)
+
+@drepl
+@xbullet<If the discriminant is of a static constrained scalar subtype, then each
+non-@b<others> @fa<discrete_choice> shall cover only values in that subtype, and
+each value of that subtype shall be covered by some @fa<discrete_choice> (either
+explicitly or by others);>
+@dby
+@xbullet<If the discriminant is of a static constrained scalar subtype, then each
+non-@b<others> @fa<discrete_choice> shall cover only values in that subtype that
+satisfy the predicate, and each value of that subtype that satisfies the predicate
+shall be covered by some @fa<discrete_choice> (either explicitly or by others);>
+
+!corrigendum 4.3.3(17)
+
+@drepl
+The @fa<discrete_choice_list> of an @fa<array_component_association> is allowed to
+have a @fa<discrete_choice> that is a nonstatic @fa<expression> or that is a
+@fa<discrete_range> that defines a nonstatic or null range, only if it is the single
+@fa<discrete_choice> of its @fa<discrete_choice_list>, and there is only one
+@fa<array_component_association> in the @fa<array_aggregate>.
+@dby
+The @fa<discrete_choice_list> of an @fa<array_component_association> is allowed to
+have a @fa<discrete_choice> that is a nonstatic @fa<choice_expression> or that is a
+@fa<subtype_indication> or @fa<range> that defines a nonstatic or null range, only
+if it is the single @fa<discrete_choice> of its @fa<discrete_choice_list>, and there
+is only one @fa<array_component_association> in the @fa<array_aggregate>.
+
+!corrigendum 4.5.2(29)
+
+@drepl
+@xbullet<The tested type is scalar, and the value of the @fa<simple_expression> belongs to the
+given @fa<range>, or the @fa<range> of the named subtype; or>
+@dby
+@xbullet<The @fa<membership_choice> is a @fa<range> and the value of the
+@fa<simple_expression> belongs to the given @fa<range>.>
+
+@xbullet<The @fa<membership_choice> is a @fa<subtype_mark>, the tested type is scalar,
+the value of the @fa<simple_expression> belongs to the range of the named subtype, and
+the predicate of the named subtype evaluates to True.>
+
+!corrigendum 4.5.2(30/2)
+
+@drepl
+The tested type is not scalar, and the value of the @fa<simple_expression> satisfies any
+constraints of the named subtype, and:
+@dby
+@xbullet<The @fa<membership_choice> is a @fa<subtype_mark>, the tested type not is
+scalar, the value of the @fa<simple_expression> satisfies any
+constraints of the named subtype, the predicate of the named subtype
+evaluates to True, and>
+
+!corrigendum 4.6(51/2)
+
+@drepl
+After conversion of the value to the target type, if the target subtype is
+constrained, a check is performed that the value satisfies this constraint.
+If the target subtype excludes null, then a check is
+made that the value is not null.
+@dby
+After conversion of the value to the target type, if the target subtype is
+constrained, a check is performed that the value satisfies this constraint.
+If the target subtype excludes null, then a check is
+made that the value is not null. If the Assertion_Policy (see 11.4.2) in effect
+is Check, the predicate of the target subtype is applied to the value and
+Assertions.Assertion_Error is raised if the result is False.
+
+!corrigendum 4.9(26)
+
+@drepl
+A @i<static subtype> is either a @i<static scalar subtype> or a @i<static
+string subtype>. A static scalar subtype is an unconstrained scalar subtype
+whose type is not a descendant of a formal type, or a constrained
+scalar subtype formed by imposing a compatible static constraint on a static
+scalar subtype. A static string subtype is an unconstrained string subtype
+whose index subtype and component subtype are static, or a constrained string
+subtype formed by imposing a compatible static constraint on a static string
+subtype. In any case, the subtype of a generic formal object of mode @b<in
+out>, and the result subtype of a generic formal function, are not static.
+@dby
+A @i<static subtype> is either a @i<static scalar subtype> or a @i<static
+string subtype>. A static scalar subtype is an unconstrained scalar subtype
+whose type is not a descendant of a formal type, or a constrained
+scalar subtype formed by imposing a compatible static constraint on a static
+scalar subtype. A static string subtype is an unconstrained string subtype
+whose index subtype and component subtype are static, or a constrained string
+subtype formed by imposing a compatible static constraint on a static string
+subtype. In any case, the subtype of a generic formal object of mode @b<in
+out>, and the result subtype of a generic formal function, are not static.
+Also, a subtype is not static if any Dynamic_Predicate specifications apply
+to it.
+
+!corrigendum 4.9.1(2/2)
+
+@drepl
+A subtype @i<statically matches> another subtype of the same type if they have
+statically matching constraints, and, for access subtypes, either both or
+neither exclude null. Two anonymous access-to-object subtypes statically match
+if their designated subtypes statically match, and either both or neither
+exclude null, and either both or neither are access-to-constant. Two anonymous
+access-to-subprogram subtypes statically match if their designated profiles are
+subtype conformant, and either both or neither exclude null.
+@dby
+A subtype @i<statically matches> another subtype of the same type if they have
+statically matching constraints, all predicate specifications that apply to
+them come from the same declarations, and, for access subtypes, either both or
+neither exclude null. Two anonymous access-to-object subtypes statically match
+if their designated subtypes statically match, and either both or neither
+exclude null, and either both or neither are access-to-constant. Two anonymous
+access-to-subprogram subtypes statically match if their designated profiles are
+subtype conformant, and either both or neither exclude null.
+
+!corrigendum 4.9.1(4)
+
+@drepl
+A constraint is @i<statically compatible> with a scalar subtype if it statically
+matches the constraint of the subtype, or if both are static and the
+constraint is compatible with the subtype. A constraint is @i<statically
+compatible> with an access or composite subtype if it statically matches
+the constraint of the subtype, or if the subtype is unconstrained.
+One subtype is @i<statically compatible> with a second subtype if the
+constraint of the first is statically compatible with the second
+subtype.
+@dby
+A constraint is @i<statically compatible> with a scalar subtype if it statically
+matches the constraint of the subtype, or if both are static and the
+constraint is compatible with the subtype. A constraint is @i<statically
+compatible> with an access or composite subtype if it statically matches
+the constraint of the subtype, or if the subtype is unconstrained.
+
+Two statically matching subtypes are statically compatible with each other.
+In addition, a subtype @i<S1> is statically compatible with a subtype @i<S2> if:
+
+@xbullet<the constraint of @i<S1> is statically compatible with @i<S2>, and>
+
+@xbullet<if @i<S2> excludes null, so does @i<S1>, and>
+
+@xbullet<either:>
+
+@xinbull<all predicate specifications that apply to @i<S2> apply also to @i<S1>, or>
+
+@xinbull<both subtypes are static, and every value that obeys the predicate of
+@i<S1> also obeys the predicate of @i<S2>.>
+
+!corrigendum 5.4(5)
+
+@drepl
+The @fa<expression>s and @fa<discrete_range>s given as @fa<discrete_choice>s of a
+@fa<case_statement> shall be static. A @fa<discrete_choice> @b<others>, if present,
+shall appear alone and in the last @fa<discrete_choice_list>.
+@dby
+The @fa<choice_expression>s, @fa<subtype_indication>s, and @fa<ranges>s given as
+@fa<discrete_choice>s of a @fa<case_statement> shall be static. A @fa<discrete_choice>
+@b<others>, if present, shall appear alone and in the last @fa<discrete_choice_list>.
+
+!corrigendum 5.4(7)
+
+@drepl
+@Xbullet<If the @fa<expression> is a @fa<name> (including a
+@fa<type_conversion> or a @fa<function_call>)
+having a static and constrained nominal subtype, or is a
+@fa<qualified_expression> whose @fa<subtype_mark> denotes a static and
+constrained scalar subtype, then each non-@b<others> @fa<discrete_choice>
+shall cover only values in that subtype, and each value of that
+subtype shall be covered by some @fa<discrete_choice>
+(either explicitly or by @b<others>).>
+@dby
+@Xbullet<If the @i<selecting_>@fa<expression> is a @fa<name> (including a
+@fa<type_conversion>, a @fa<qualified_expression>, or a @fa<function_call>)
+having a static and constrained nominal subtype, then each non-@b<others>
+@fa<discrete_choice> shall cover only values in that subtype that satisfy
+the predicate, and each value of that subtype that satisfies the predicate
+shall be covered by some @fa<discrete_choice> (either explicitly or by @b<others>).>
+
+!corrigendum 6.4.1(13)
+
+@drepl
+@xinbull<For an access type, the formal parameter is initialized from the value of the actual,
+without a constraint check;>
+@dby
+@xinbull<For an access type, the formal parameter is initialized from the value of the
+actual, without checking that the value satisfies any constraint, any predicate, or any exclusion
+of the null value;>
+
+@xinbull<For a scalar type that has the Default_Value aspect specified, the formal parameter
+is initialized from the value of the actual, without checking that the value satisfies
+any constraint or any predicate;>
+
+!corrigendum 13.9.2(3)
+
+@drepl
+@xhang<@xterm<X'Valid>
+Yields True if and only if the object denoted by X is normal and has a valid representation.
+The value of this attribute is of the predefined type Boolean.
+@dby
+@xhang<@xterm<X'Valid>
+Yields True if and only if the object denoted by X is normal, has a valid representation,
+and the predicate of the nominal subtype of X evaluates to True.
+The value of this attribute is of the predefined type Boolean.
+
 !ACATS test
 
 Add ACATS B and C tests for this feature.
@@ -2884,5 +3250,568 @@
 Gary suggested getting rid of this term altogether, but that would require
 saying "specification of a predicate aspect" or some such, which is a bit of a
 mouthful, and it's used many times, so I went with Tucker's suggestion.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, May 6, 2011  9:54 PM
+
+This one probably doesn't need to be answered (since it seems obvious), but as
+it is fairly significant, I wanted to mention it. [Oops; after writing it I
+found a more signficant problem. See the bottom. - RLB]
+
+In AI05-0153-3 (Subtype Predicates), the grammar for discrete_choices was
+changed from:
+
+5     discrete_choice ::= expression | discrete_range | others
+
+to (including the AI05-0158-1 change):
+
+5     discrete_choice ::= choice_expression | *discrete_*subtype_indication
+| range | others
+
+[BTW, the AI had "discrete_subtype_indication", but there is no such thing. I
+got errors from the RM tool which makes links for all non-terminal references -
+which doesn't work for non-existent NTs. This change seems to have been lifted
+from 3.6, where subtype_indication has a "discrete" prefix, so that's what I did
+here.]
+
+3.8.1(8) starts:
+
+The expressions and discrete_ranges given as discrete_choices in a variant_part
+shall be static. ...
+
+Wait a minute -- what "discrete_ranges"?? There aren't any in the grammar!
+Similarly, "expressions" is vaguely wrong. So I replaced this by:
+
+The choice_expressions, subtype_indications, and ranges given as
+discrete_choices in a variant_part shall be static. ...
+
+The same thing needs to be done in 5.4(5) [it's virtually the same text].
+
+----------------------------
+
+Oh-oh: discrete_choice is also used by array aggregates. 4.3.3(17) also needs to
+be fixed:
+
+"...that is a subtype_indication or range that defines a nonstatic or null
+range..."
+
+However, talking about discrete_ranges made subtypes with predicates illegal in
+array aggregates (which is what we want, I think); now there is no such
+requirement. We could add some text to 3.2.4 to cover this case, but it's not
+clear exactly what it should be or whether the modified definition of choice
+coverage causes problems. So I'm not sure what wording needs to be added here.
+
+Humm, the wording that Bob proposed doesn't seem to mention array aggregates in
+the places where predicate subtypes aren't allowed. Was that an oversight or
+intentional?? (Recall that array aggregate choices don't have to be static, so
+we seem to be allowing dynamic predicates here. Yikes!)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Saturday, May 7, 2011  10:40 AM
+
+...
+> [BTW, the AI had "discrete_subtype_indication", but there is no such thing.
+> I got errors from the RM tool which makes links for all non-terminal
+> references - which doesn't work for non-existent NTs. This change
+> seems to have been lifted from 3.6, where subtype_indication has a
+> "discrete" prefix, so that's what I did here.]
+
+Good.  At least there's SOME regression testing on the RM.  ;-)
+
+> 3.8.1(8) starts:
+>
+> The expressions and discrete_ranges given as discrete_choices in a
+> variant_part shall be static. ...
+>
+> Wait a minute -- what "discrete_ranges"?? There aren't any in the grammar!
+> Similarly, "expressions" is vaguely wrong. So I replaced this by:
+>
+> The choice_expressions, subtype_indications, and ranges given as
+> discrete_choices in a variant_part shall be static. ...
+>
+> The same thing needs to be done in 5.4(5) [it's virtually the same text].
+
+OK.
+
+> ----------------------------
+>
+> Oh-oh: discrete_choice is also used by array aggregates. 4.3.3(17)
+> also needs to be fixed:
+>
+> "...that is a subtype_indication or range that defines a nonstatic or
+> null range..."
+>
+> However, talking about discrete_ranges made subtypes with predicates
+> illegal in array aggregates (which is what we want, I think); ...
+
+The intent is that Static_Predicates can be used whereever full coverage rules
+apply.  So you can say:
+
+    subtype Upper is Character range 'A'..'Z';
+    subtype Lower is Character range 'a'..'z';
+    subtype Letter is Character with
+        Static_Predicate => Letter in Upper or Letter in Lower;
+
+    Is_Letter: constant array(Character) of Boolean
+        := (Letter => True, others => False);
+
+or:
+
+    Is_Letter: constant array(Character) of Boolean
+        := (Upper => True, Lower => True, others => False);
+
+Dynamic_Predicates, on the other hand, are trouble.
+
+>...now there is no such
+> requirement. We could add some text to 3.2.4 to cover this case, but
+>it's  not clear exactly what it should be or whether the modified
+>definition of  choice coverage causes problems. So I'm not sure what
+>wording needs to be  added here.
+>
+> Humm, the wording that Bob proposed doesn't seem to mention array
+> aggregates in the places where predicate subtypes aren't allowed. Was
+> that an oversight or intentional??
+
+The dynamic part was an oversight.
+
+> ...(Recall that array aggregate choices don't have to be static, so we
+> seem to be allowing dynamic predicates here. Yikes!)
+
+Well, a nonstatic subtype_indication is currently only allowed when there is
+exacty one choice.  I suggest you modify this paragraph of the AI:
+
+The discrete_subtype_definition of a loop_parameter_specification shall not
+denote a subtype to which Dynamic_Predicate specifications apply.
+
+as follows:
+
+The discrete_subtype_definition of a loop_parameter_specification {or a
+discrete_choice of a named_array_aggregate} shall not denote a subtype to which
+Dynamic_Predicate specifications apply.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, May 9, 2011  8:31 PM
+
+...
+> > [BTW, the AI had "discrete_subtype_indication", but there is no such thing.
+> > I got errors from the RM tool which makes links for all non-terminal
+> > references - which doesn't work for non-existent NTs. This change
+> > seems to have been lifted from 3.6, where subtype_indication has a
+> > "discrete" prefix, so that's what I did here.]
+>
+> Good.  At least there's SOME regression testing on the RM.  ;-)
+
+There's actually another such test: Pascal created a tool last time to compare
+the Amendment document (that is, the !corrigendum sections) to the text in the
+Standard. However, I'm not sure I know how to use it (or if I have the most
+recent source); I recall that he didn't let me use it again after I spent
+several hours attempting to use an early version and wrote him a lengthy message
+complaining about it. :-)
+
+...
+> > Oh-oh: discrete_choice is also used by array aggregates. 4.3.3(17)
+> > also needs to be fixed:
+> >
+> > "...that is a subtype_indication or range that defines a nonstatic
+> > or null range..."
+> >
+> > However, talking about discrete_ranges made subtypes with predicates
+> > illegal in array aggregates (which is what we want, I think); ...
+>
+> The intent is that Static_Predicates can be used whereever full
+> coverage rules apply.  So you can say:
+>
+>     subtype Upper is Character range 'A'..'Z';
+>     subtype Lower is Character range 'a'..'z';
+>     subtype Letter is Character with
+>         Static_Predicate => Letter in Upper or Letter in Lower;
+>
+>     Is_Letter: constant array(Character) of Boolean
+>         := (Letter => True, others => False);
+>
+> or:
+>
+>     Is_Letter: constant array(Character) of Boolean
+>         := (Upper => True, Lower => True, others => False);
+
+OK. It is odd that you can't declare an array subtype using a subtype with a
+predicate, but you can write the similar aggregate.
+
+    subtype Smallish is Positive
+       with Static_Predicate => Smallish <= 10;
+
+   Odd : String(Smallish) -- Illegal.
+      := (Smallish => ' '); -- Legal.
+
+But that doesn't seem critical - it only would work when the predicate should
+have been written as a range (else the aggregate would violate 4.3.3(18)).
+
+> Dynamic_Predicates, on the other hand, are trouble.
+
+Right. I was thinking about the above oddity and the dynamic cases when I was
+thinking about this.
+
+> >...now there is no such
+> > requirement. We could add some text to 3.2.4 to cover this case, but
+> >it's  not clear exactly what it should be or whether the modified
+> >definition of  choice coverage causes problems. So I'm not sure what
+> >wording needs to be  added here.
+> >
+> > Humm, the wording that Bob proposed doesn't seem to mention array
+> > aggregates in the places where predicate subtypes aren't allowed.
+> > Was that an oversight or intentional??
+>
+> The dynamic part was an oversight.
+>
+> > ...(Recall that array aggregate choices don't have to be static, so
+> > we seem to be allowing dynamic predicates here. Yikes!)
+>
+> Well, a nonstatic subtype_indication is currently only allowed when
+> there is exacty one choice.  I suggest you modify this paragraph of
+> the AI:
+>
+> The discrete_subtype_definition of a
+> loop_parameter_specification shall not denote a subtype to which
+> Dynamic_Predicate specifications apply.
+>
+> as follows:
+>
+> The discrete_subtype_definition of a
+> loop_parameter_specification {or a discrete_choice of a
+> named_array_aggregate} shall not denote a subtype to which
+> Dynamic_Predicate specifications apply.
+
+OK, I'll do that.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, May 06, 2011 8:21 PM
+
+I'm working on putting the large AIs into the Standard, and sometimes the
+juxtaposition highlights things that I wouldn't otherwise think of. I just
+finished AI05-0228-1, which changes 13.13.2(35) to use "implicit initial values"
+(in order that Default_Value and Default_Component_Value are captured). [Note
+that the term "implicit initial values" dates back at least to Ada 95, we just
+extended it a bit.]
+
+I then am working on the following Dynamic Semantics paragraph from 3.2.4 (from
+AI05-0153-3):
+
+If the Assertion_Policy (see 11.4.2) in effect is Check, then:
+
+  On every subtype conversion, the predicate of the target subtype is
+  evaluated, and a check is made that the predicate is True. This includes all
+  parameter passing, except for certain parameters passed by reference, which
+  are covered by the following rule: After normal completion and leaving of a
+  subprogram, for each in out or out parameter that is passed by reference, the
+  predicate of the subtype of the actual is evaluated, and a check is made that
+  the predicate is True. For an object created by an object_declaration with no
+  explicit initialization expression, or by an uninitialized allocator,
+  if any subcomponents have explicit default values, the predicate of the nominal
+  subtype is evaluated, and a check is made that the predicate is True.
+  Assertions.Assertion_Error is raised if any of these checks fail.
+
+My first concern is "explicit default values". I'm not quite sure what this is
+supposed to mean, but I would think it either should use the old wording of
+13.13.2 (component_declarations with default_expressions) or the new wording
+(implicit initial values). Note that "implicit initial values" is a forward
+reference here, it will need (see 3.3.1) following. I think you meant the
+latter, but I'm not certain. I'll use the "implicit initial values" unless
+someone objects. [Aside: It's funny that the "correct" wording is exactly the
+reverse of what you said.]
+
+My second concern is with "the predicate of the nominal subtype is evaluated".
+When I first (re)read this, I thought it was talking about the subtype of the
+subcomponents. That doesn't make any sense (the subtype conversion of the
+default expression - however that is determined - will evaluate the
+predicate(s)). I now think that you are talking about the nominal subtype of the
+object declaration or allocator. I think we have to say that, because the
+wording doesn't associate well otherwise.
+
+So we get:
+
+  On every subtype conversion, the predicate of the target subtype is
+  evaluated, and a check is made that the predicate is True. This includes all
+  parameter passing, except for certain parameters passed by reference, which
+  are covered by the following rule: After normal completion and leaving of a
+  subprogram, for each in out or out parameter that is passed by reference, the
+  predicate of the subtype of the actual is evaluated, and a check is made that
+  the predicate is True. For an object created by an object_declaration with no
+  explicit initialization expression, or by an uninitialized allocator,
+  if any subcomponents have implicit initial values, the predicate of the nominal
+  subtype of the object_declaration or allocator is evaluated, and a check is made
+  that the predicate is True. Assertions.Assertion_Error is raised if any of these
+  checks fail.
+
+Is this what you meant, or is it something else??
+
+****************************************************************
+
+From: Bob Duff
+Sent: Saturday, May 07, 2011 10:38 AM
+
+> I'm working on putting the large AIs into the Standard, and sometimes
+> the juxtaposition highlights things that I wouldn't otherwise think of.
+
+I'm sure there will be lots more such cases.  And I'm sure some of them will
+slip through unnoticed, and we'll have to fix them with Ada 2012 AIs.
+
+>... I just
+> finished AI05-0228-1, which changes 13.13.2(35) to use "implicit
+>initial  values" (in order that Default_Value and
+>Default_Component_Value are  captured). [Note that the term "implicit
+>initial values" dates back at least  to Ada 95, we just extended it a
+>bit.]
+>
+> I then am working on the following Dynamic Semantics paragraph from
+> 3.2.4 (from AI05-0153-3):
+>
+> If the Assertion_Policy (see 11.4.2) in effect is Check, then:
+>
+>   On every subtype conversion, the predicate of the target subtype is
+>   evaluated, and a check is made that the predicate is True. This includes all
+>   parameter passing, except for certain parameters passed by reference, which
+>   are covered by the following rule: After normal completion and leaving of a
+>   subprogram, for each in out or out parameter that is passed by reference, the
+>   predicate of the subtype of the actual is evaluated, and a check is made that
+>   the predicate is True. For an object created by an object_declaration with no
+>   explicit initialization expression, or by an uninitialized allocator,
+>   if any subcomponents have explicit default values, the predicate of the nominal
+>   subtype is evaluated, and a check is made that the predicate is True.
+>   Assertions.Assertion_Error is raised if any of these checks fail.
+>
+> My first concern is "explicit default values". I'm not quite sure what
+> this is supposed to mean,...
+
+It's supposed to mean that somebody wrote ":= <something>" on a component
+declaration, for some subcomponent of the type.  Implicit initial values, such
+as "null", and those defined by Default_[Component_]Value, don't count.
+
+>...but I would think it either should use the old wording  of 13.13.2
+>(component_declarations with default_expressions)
+
+I'm not sure which "old wording" you're referring to, but yes,
+"component_declarations with default_expressions" is what I meant.
+
+>... or the new wording (implicit initial values).
+
+That would be wrong.
+
+>... Note that "implicit initial values" is a  forward reference here,
+>it will need (see 3.3.1) following. I think you  meant the latter, but
+>I'm not certain. I'll use the "implicit initial  values" unless someone
+>objects.
+
+I object.
+
+>...[Aside: It's funny that the "correct"
+> wording is exactly the reverse of what you said.]
+
+I think I said what I meant, even if I didn't use proper RM jargon.  ;-)
+
+> My second concern is with "the predicate of the nominal subtype is
+> evaluated". When I first (re)read this, I thought it was talking about
+> the subtype of the subcomponents. That doesn't make any sense (the
+> subtype conversion of the default expression - however that is
+> determined - will evaluate the predicate(s)).
+
+Right, that doesn't make sense.
+
+>...I now think that you are talking about the  nominal subtype of the
+>object declaration or allocator.
+
+Right.  Except that's not proper RM jargon.  You should add "of the object"
+after "nominal subtype".  Or if you think that's still unclear, add "of the
+created object".
+
+>...I think we have to
+> say that, because the wording doesn't associate well otherwise.
+>
+> So we get:
+>
+>   On every subtype conversion, the predicate of the target subtype is
+>   evaluated, and a check is made that the predicate is True. This includes all
+>   parameter passing, except for certain parameters passed by reference, which
+>   are covered by the following rule: After normal completion and leaving of a
+>   subprogram, for each in out or out parameter that is passed by reference, the
+>   predicate of the subtype of the actual is evaluated, and a check is made that
+>   the predicate is True. For an object created by an object_declaration with no
+>   explicit initialization expression, or by an uninitialized allocator,
+>   if any subcomponents have implicit initial values, the predicate of the nominal
+>   subtype of the object_declaration or allocator is evaluated, and a check is made
+>   that the predicate is True. Assertions.Assertion_Error is raised if any of these
+>   checks fail.
+>
+> Is this what you meant, or is it something else??
+
+Something else.  ;-)  See above.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, May 09, 2011 9:50 PM
+
+...
+> > I then am working on the following Dynamic Semantics paragraph from
+> > 3.2.4 (from AI05-0153-3):
+> >
+> > If the Assertion_Policy (see 11.4.2) in effect is Check, then:
+> > ... For an object created by an object_declaration with no
+> >   explicit initialization expression, or by an uninitialized allocator,
+> >   if any subcomponents have explicit default values, the predicate
+> >   of the nominal
+> >   subtype is evaluated, and a check is made that the predicate is True.
+> >   Assertions.Assertion_Error is raised if any of these checks fail.
+> >
+> > My first concern is "explicit default values". I'm not quite sure
+> > what this is supposed to mean,...
+>
+> It's supposed to mean that somebody wrote ":= <something>" on a
+> component declaration, for some subcomponent of the type.
+> Implicit initial values, such as "null", and those defined by
+> Default_[Component_]Value, don't count.
+
+OK, but that's weird. We've tried to reduce/eliminate differences between
+explicit and implicit initializations. And I'm not sure that it really works
+(see below).
+
+In any case, I've fixed up the wording as you indicated for the moment, pending
+further discussion (I'm giving the author the benefit of the doubt; I don't want
+to change your intent without discussion).
+
+> >...but I would think it either should use the old wording of 13.13.2
+> >(component_declarations with default_expressions)
+>
+> I'm not sure which "old wording" you're referring to, but yes,
+> "component_declarations with default_expressions" is what I meant.
+
+OK.
+
+...
+
+> > My second concern is with "the predicate of the nominal subtype is
+> > evaluated". When I first (re)read this, I thought it was talking
+> > about the subtype of the subcomponents. That doesn't make any sense
+> > (the subtype conversion of the default expression - however that is
+> > determined - will evaluate the predicate(s)).
+>
+> Right, that doesn't make sense.
+>
+> >...I now think that you are talking about the  nominal subtype of the
+> >object declaration or allocator.
+>
+> Right.  Except that's not proper RM jargon.  You should add "of the
+> object" after "nominal subtype".  Or if you think that's still
+> unclear, add "of the created object".
+
+I'll add "of the created object", it's a bit clearer.
+
+...
+
+Now to back up a bit. The rule we're talking about now reads:
+
+For an object created by an object_declaration with no explicit initialization
+expression, or by an uninitialized allocator, if any subcomponents have
+default_expressions, the predicate of the nominal subtype of the created object
+is evaluated, and a check is made that the predicate is True.
+
+My recollection is that the purpose of this rule is to ensure that composite
+objects obey their predicate, but to avoid requiring that composite components
+are initialized when using a predicate. If we always evaluated the predicate,
+then any components that the predicate depends upon would always have to be
+initialized (else the predicate could be depending on invalid values, with the
+erratic results that follow from that). Such initializations potentially would
+have substantial runtime overhead, so we don't want to force them, and we surely
+don't want to make programmers have to choose between efficiency and using
+predicates.
+
+OTOH, if the predicate was never evaluated for such object declaration, it would
+be easy to create values that fail the predicate and the failures would occur
+much later -- making this construct much less like constraints than we would
+like. It also would make the behavior of explicitly initialized object
+declarations very different from the implicit ones, which is uncomfortable.
+
+Given this intention, it seems to me that the proposed rule fails dismally.
+
+First, there are many cases that are clearly not going to be detected by this
+rule. For instance, consider one of Bob's favorite topics, the 1-based string:
+
+     subtype One_Based_String is String
+        with Dynamic_Predicate => One_Based_String'First = 1;
+
+     Foo : One_Based_String (2 .. 10); -- No exception here!
+
+     Bar : One_Based_String (2 .. 3) := "AA"; -- Raises Assertion_Error.
+
+Depending on how Foo is used (consider using it as the first operand of a
+concatenation), the language might never actually check the predicate, meaning
+that the purpose of predicate would never be enforced.
+
+Second, it will be periodically occur that predicates are enforced on
+uninitialized components:
+
+     type Some_Rec is record
+         Count : Natural := 0;
+         Id    : Character;
+     end record;
+
+     subtype A_Rec is Some_Rec
+        with A_Rec.Id = 'A';
+
+     declare
+        A : A_Rec; -- Oops: Id is not initialized, probably will get Assertion_Error.
+     begin
+        A := (Count => 0, Id => 'A');
+        ...
+
+
+This example is contrived, but almost all of the large records that I have used
+in my programs have at least one default expression (which includes
+discriminants, of course). So the predicates would almost always be evaluated,
+and the initialization would always be forced if the predicates are to work.
+
+
+Clearly, the rule we really want is something like: "For an uninitialized object
+declaration or allocator, if all of the components that the predicate depends on
+are initialized, then the predicate is evaluated." [This is purposely sloppy -
+it's not a serious proposal.] However, it should be clear that such a rule would
+be hard to implement and would cause problems with function calls (how do you
+figure out what subcomponents a function call touches??) So the rule we really
+want is out.
+
+It's possible that Bob's current rule (and I don't think this was Bob's original
+idea, although I don't recall precisely what his original idea was) is the best
+that we can do. But I'm dubious; it misses clearly important cases as shown
+above, and *still* doesn't prevent touching uninitialized components. Clearly
+there is a trade-off here, and it isn't clear where that trade-off is.
+
+Two other options come to mind:
+
+(1) Always check the predicate in the cases noted. "If it hurts to have a
+    predicate on type Some_Rec, then don't do that." It's not the nicest
+    solution, but remember the problem only occurs on components actually
+    touched by the predicate. If you want to reference them in a predicate, then
+    you ought to at least consider initializing them. Obviously, no problem
+    cases will get through unchecked, but there is a runtime overhead and/or a
+    restriction on use that follows from it.
+
+(2) Make sure that a predicate is checked only if *all* of the components are
+    initialized. That would avoid the problem of depending on uninitialized
+    components, with the result of precates being evaluated much less often on
+    uninitialized objects. One could imagine tweaking this based on the actual
+    predicate expressions (only requiring components that are touched if there
+    are no user-defined functions), but that probably wouldn't help much.
+
+I have to admit that none of these options seems particularly pleasant. I'd
+probably lean toward (1) [rather than the current proposal] because it is
+simpler and less surprising to users (even if a bit more of a pain), but perhaps
+there is something better out there.
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent