Version 1.4 of ai12s/ai12-0432-1.txt

Unformatted version of ai12s/ai12-0432-1.txt version 1.4
Other versions for file ai12s/ai12-0432-1.txt

!standard 3.2.4(31/5)          21-06-04 AI12-0432-1/03
!standard 4.6(51.1/5)
!class binding interpretation 21-06-03
!status Amendment 1-2012 21-06-04
!status ARG Approved 14-0-0 21-06-03
!status work item 21-05-28
!status received 21-05-28
!priority Low
!difficulty Easy
!subject View conversions of assignments and predicate checks
!summary
Exclude view conversions of targets of assignment_statements from predicate checks.
!question
We have decided that no predicate checks should be performed "on the way in" for an OUT parameter. It seems the same should apply to a view conversion applied to the LHS of a (tagged) assignment. If the specified subtype has a predicate, the value being assigned should be checked that it satisfies the predicate, but there seems no reason the prior value of the LHS should satisfy the predicate. For example:
subtype Is_Boiling is Some_Tagged_Type with with Dynamic_Predicate => Is_Boiling.Temp_In_Celsius >= 100;
Is_Boiling(X) := (Temp_In_Celsius => 101, ...); -- should be OK even if X.Temp_In_Celsius < 100 before the assignment.
Should this be changed? (Yes.)
!recommendation
(See Summary.)
!wording
Modify 3.2.4(31/5):
[Redundant: On a subtype conversion, a check is performed that the operand satisfies the predicates of the target subtype, [unless it is a conversion for an actual parameter of mode out] {except for certain view conversions} (see 4.6). ...
Modify 4.6(51.1/5):
a view conversion that is {the target of an assignment statement and is not referenced with a target_name, or} an actual parameter of mode out; or
!discussion
A reference to a target via a target_name ('@') is a read of the object, and it would be unusual if it didn't meet the predicate of its nominal subtype. But there's no need for the object being written to meet the predicate (only the source expression needs to do that).
!corrigendum 3.2.4(31/5)
Replace the paragraph:
On a subtype conversion, a check is performed that the operand satisfies the predicates of the target subtype, unless it is a conversion for an actual parameter of mode out (see 4.6). In addition, after normal completion and leaving of a subprogram, for each in out or out parameter that is passed by reference, a check is performed that the value of the parameter satisfies the predicates of the subtype of the actual. For an object created by an object_declaration with no explicit initialization expression, or by an uninitialized allocator, if the types of any parts have specified Default_Value or Default_Component_Value aspects, or any subcomponents have default_expressions, a check is performed that the value of the created object satisfies the predicates of the nominal subtype.
by:
On a subtype conversion, a check is performed that the operand satisfies the predicates of the target subtype, except for certain view conversions (see 4.6). In addition, after normal completion and leaving of a subprogram, for each in out or out parameter that is passed by reference, a check is performed that the value of the parameter satisfies the predicates of the subtype of the actual. For an object created by an object_declaration with no explicit initialization expression, or by an uninitialized allocator, if the types of any parts have specified Default_Value or Default_Component_Value aspects, or any subcomponents have default_expressions, a check is performed that the value of the created object satisfies the predicates of the nominal subtype.
!corrigendum 4.6(51/4)
Replace the paragraph:
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 predicate checks are enabled for the target subtype (see 3.2.4), a check is performed that the value satisfies the predicates of the target subtype.
by:
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 predicate checks are enabled for the target subtype (see 3.2.4), a check is performed that the value satisfies the predicates of the target subtype, unless the conversion is:
!ASIS
No ASIS change.
!ACATS test
An ACATS C-Test is needed to make sure no check is made in this case, and that the check is made on the source expression and on any target_names.
!appendix

From WG 9 review issue #113 (Tucker Taft)

We have decided that no predicate checks should be performed "on the way in"
for an OUT parameter. It seems the same should apply to a view conversion 
applied to the LHS of a (tagged) assignment. If the specified subtype has a 
predicate, the value being assigned should be checked that it satisfies the 
predicate, but there seems no reason the prior value of the LHS should satisfy
the predicate. E.g.:

   subtype Is_Boiling is Some_Tagged_Type with Is_Boiling.Temp_In_Celsius >= 100;

   Is_Boiling(X) := (Temp_In_Celsius => 101, ...);
      -- should be OK even if X.Temp_In_Celsius < 100 before the assignment.

I would suggest we alter 4.6(51.1/5) as follows:

        a view conversion that is {the target of an assignment or} an actual
        parameter of mode out; or

A similar fix is needed in 3.2.4(31/5):

    [Redundant: On a subtype conversion, a check is performed that the operand 
    satisfies the predicates of the target subtype, unless it is a conversion
    for {the target of an assignment or} an actual parameter of mode 
    out (see 4.6).] ...

---

We need to take references by "target_name" into account ('@'), which leads to 
something like:

Modify 4.6(51.1/5):

        a view conversion that is {the target of an assignment statement and 
        is not referenced with a target_name, or} an actual parameter of 
        mode out; or

It is painful to have to copy all of this into 3.2.4(31/5), so perhaps we could say:

    [Redundant: On a subtype conversion, a check is performed that the operand 
    satisfies the predicates of the target subtype, [unless it is a conversion 
    for] {except for certain view conversions applied to the target of an 
    assignment or} an actual parameter of mode out (see 4.6).]

[Editor's comment:]

If we're going to simplify 3.2.4(31/5) anyway, why don't we go all the way and
just say "except for certain view conversions (see 4.6)"? The less text we 
duplicate, the better, and this is already marked as redundant. We just don't 
want this to be wrong (since Redundant markings aren't normative, so this text 
is normative).

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


Questions? Ask the ACAA Technical Agent