Version 1.10 of ais/ai-00171.txt

Unformatted version of ais/ai-00171.txt version 1.10
Other versions for file ais/ai-00171.txt

!standard 03.08 (18)          00-07-13 AI95-00171/09
!standard 03.03.01 (18)
!standard 03.06 (22)
!standard 04.03.01 (19)
!standard 04.08 (10)
!standard 09.04 (14)
!standard 09.05.02 (22)
!class binding interpretation 98-03-19
!status Corrigendum 2000 99-08-17
!status WG9 approved 98-06-12
!status ARG Approved 11-0-1 98-04-01
!status received 96-11-16
!priority Low
!difficulty Hard
!qualifier Omission
!subject Elaboration of subtype_indications with per-object constraints
!summary
The elaboration of a subtype indication with a per-object constraint occurs when an object of the enclosing type is created. This elaboration consists of the evaluation of each per-object expression of the constraint, followed by the usual actions associated with such elaboration, but using the values for any expressions that are not part of a per-object expression that were determined earlier when the type definition was elaborated.
For evaluating a named association applying to multiple components in a per-object discriminant constraint, if the expression of the association is not part of a per-object expression, then it must be evaluated once for each associated component.
!question
When does the elaboration of a subtype indication with a per-object constraint occur? What are the actions of such an elaboration?
When a component has a subtype_indication with a per-object constraint and an object of the type containing the component is declared, the subtype_indication containing the per-object constraint is apparently never elaborated.
3.8(18) explains that subtype_indications with per-object constraints are not elaborated, but that any expressions that are not part of a per-object expression are evaluated. However, what to do with the results of those evaluations never seems to be explained.
3.3.1(15-20) describes the process of elaborating an object_declaration. In step 3, per-object expressions are evaluated, but there is no mention of elaborating anything, although later paragraph 20 does seem to imply that some sort of elaborations were supposed to have taken place in step 3.
The elaboration of per-object constraints is mentioned in (at least) the following other places where objects are created:
4.3.1(19) creating record aggregates
4.8(10) creating heap objects via uninitialized allocators
9.4(14) creating a protected object (This one is supposed to be redundant
with 3.3.1, but in fact the two appear to be inconsistent.)
According to a strict reading, elaborating the per-object constraint would appear to involve reevaluating the non-per-object expressions (since there doesn't seem to be any separate definition of what happens when a per-object constraint is elaborated), but not include any subtype compatibility checks that would normally occur as part of subtype elaboration (since elaboration of the subtype_indication containing the constraint isn't mentioned in these paragraphs). What are the intended semantics?
!recommendation 98-03-19
Notwithstanding the rules given in 3.3.1(18), 4.3.1(19), and 4.8(10), the elaboration of the subtype indication of a component definition with a per-object constraint occurs when an object of the enclosing type is created. This elaboration takes place on elaboration of an object declaration, evaluation of an uninitialized allocator, and when evaluating an aggregate of the type.
The elaboration consists of the evaluation of each per-object expression of the component's constraint, followed by the conversion of the value of each expression of the constraint to its appropriate expected type and the performance of the compatibility check defined for the elaboration of the subtype indication (see 3.2.2(11)). The values used for any expressions that are not part of per-object expressions of the subtype's constraint are those determined during the original elaboration of the component definition as defined in 3.8(18). Such expressions are not reevaluated during elaboration of the per-object constraint that occurs as part of object creation, despite any rules that state when a per-object constraint is elaborated (e.g., as part of evaluating an allocator or aggregate).
Note further that the evaluation of expressions in a per-object constraint defined in 3.8(18) was intended to take into account the case of named associations for multiple components in a discriminant constraint. For such an association, the expression must be evaluated once for each associated component, as prescribed by 3.7.1(12).
!wording
Changes are required in 3.3.1(18), 4.3.1(19), 4.8(10), and 9.4(14) to state that any subtype indications for components with a per-object constraint are elaborated. The specific actions of elaborating such subtype indications and their associated constraints, as described in the recommendation, should be defined (perhaps in 3.8(18)). Also, 3.8(18) needs to account for multiple evaluations of non-per-object expressions in the case of named associations in a per-object discriminant constraint.
!discussion
There are two basic problems with the current wording of the standard regarding the elaboration of components with a per-object constraint. The first is that the rules don't explain what is done with the values obtained from expressions that are not part of per-object expressions (as defined in 3.8(18)) or whether such expression are reevaluated when a per-object constraint is later elaborated during object creation. The other problem is that the mention of elaboration of per-object constraints in rules such as 4.3.1(19) and 4.8(10) fails to cover the need for the subtype compatibility check that is normally performed when elaborating a subtype indication.
The intent was clearly that the values of the expressions evaluated as part of elaborating a component definition with a per-object constraint (3.8(18)) should be used later when creating an object of the containing type. It would not make sense to discard the values already determined and to reevaluate the expressions (especially if they have side effects). The description in the rules for allocator and aggregate evaluation that states that a per-object constraint is elaborated should mention that only the per-object expressions are evaluated at that point and that the values for other expressions are those determined earlier when the type was elaborated. (The description of the semantics of elaborating per-object constraints should really be centralized in a single place, such as 3.8(18).)
The rules for object declarations, allocator evaluation, and aggregate evaluation all fail to require the subtype compatibility check that occurs when a subtype indication is elaborated (and for object declarations even the constraint elaboration is omitted). This check is certainly needed in these cases as well. The fix for this oversight is to define each of these rules to include the elaboration of the subtype indications for components with per-object constraints (which also subsumes the elaboration of the constraint itself).
One other minor gap is that the case of elaborating a named discriminant association within a per-object constraint is not covered by that rule in 3.8(18). The rule as given only describes a single evaluation for each expression of the constraint, but the intent is that for a named association the expression should be evaluated for each associated component.
!corrigendum 3.03.01(18)
Replace the paragraph:
3.
The object is created, and, if there is not an initialization expression, any per-object expressions (see 3.8) are evaluated and any implicit initial values for the object or for its subcomponents are obtained as determined by the nominal subtype.
by:
3.
The object is created, and, if there is not an initialization expression, any per-object constraints (see 3.8) are elaborated and any implicit initial values for the object or for its subcomponents are obtained as determined by the nominal subtype.
!corrigendum 3.06(22)
Replace the paragraph:
The elaboration of a discrete_subtype_definition creates the discrete subtype, and consists of the elaboration of the subtype_indication or the evaluation of the range. The elaboration of a component_definition in an array_type_definition consists of the elaboration of the subtype_indication. The elaboration of any discrete_subtype_definitions and the elaboration of the component_definition are performed in an arbitrary order.
by:
The elaboration of a discrete_subtype_definition that does not contain any per-object expressions creates the discrete subtype, and consists of the elaboration of the subtype_indication or the evaluation of the range. The elaboration of a discrete_subtype_definition that contains one or more per-object expressions is defined in 3.8. The elaboration of a component_definition in an array_type_definition consists of the elaboration of the subtype_indication. The elaboration of any discrete_subtype_definitions and the elaboration of the component_definition are performed in an arbitrary order.
!corrigendum 3.08(18)
Replace the paragraph:
Within the definition of a composite type, if a component_definition or discrete_subtype_definition (see 9.5.2) includes a name that denotes a discriminant of the type, or that is an attribute_reference whose prefix denotes the current instance of the type, the expression containing the name is called a per-object expression, and the constraint being defined is called a per-object constraint. For the elaboration of a component_definition of a component_declaration, if the constraint of the subtype_indication is not a per-object constraint, then the subtype_indication is elaborated. On the other hand, if the constraint is a per-object constraint, then the elaboration consists of the evaluation of any included expression that is not part of a per-object expression.
by:
Within the definition of a composite type, if a component_definition or discrete_subtype_definition (see 9.5.2) includes a name that denotes a discriminant of the type, or that is an attribute_reference whose prefix denotes the current instance of the type, the expression containing the name is called a per-object expression, and the constraint or range being defined is called a per-object constraint. For the elaboration of a component_definition of a component_declaration or the discrete_subtype_definition of an entry_declaration for an entry family (see 9.5.2), if the constraint or range of the subtype_indication or discrete_subtype_definition is not a per-object constraint, then the subtype_indication or discrete_subtype_definition is elaborated. On the other hand, if the constraint or range is a per-object constraint, then the elaboration consists of the evaluation of any included expression that is not part of a per-object expression. Each such expression is evaluated once unless it is part of a named association in a discriminant constraint, in which case it is evaluated once for each associated discriminant.
When a per-object constraint is elaborated (as part of creating an object), each per-object expression of the constraint is evaluated. For other expressions, the values determined during the elaboration of the component_definition or entry_declaration are used. Any checks associated with the enclosing subtype_indication or discrete_subtype_definition are performed, including the subtype compatibility check (see 3.2.2), and the associated subtype is created.
!corrigendum 4.08(10)
Replace the paragraph:
by:
!corrigendum 9.05.02(22)
Replace the paragraph:
For the elaboration of an entry_declaration for an entry family, if the discrete_subtype_definition contains no per-object expressions (see 3.8), then the discrete_subtype_definition is elaborated. Otherwise, the elaboration of the entry_declaration consists of the evaluation of any expression of the discrete_subtype_definition that is not a per-object expression (or part of one). The elaboration of an entry_declaration for a single entry has no effect.
by:
The elaboration of an entry_declaration for an entry family consists of the elaboration of the discrete_subtype_definition, as described in 3.8. The elaboration of an entry_declaration for a single entry has no effect.
!ACATS test
An extensive set of tests check cases where a constraint contains an enclosing discriminant in component_definitions (C37213x and C37215x).
C-Tests should be constructed to check that these rules are enforced on per-object constraints in task and protected specifications, and that the checks are made when the per-object expression contains a attribute whose prefix denotes the current instance of the type.
!appendix

!section 3.8(18)
!subject Elaboration of subtype_indications with per-object constraints
!reference RM95-3.8(18)
!from Vince Del Vecchio 96-10-30
!reference 1996-5737.a Vince Del Vecchio  1996-10-30>>
!discussion

When a component has a subtype_indication with a per-object constraint
and an object of the type containing the component is declared, the
subtype_indication containing the per-object constraint is apparently
never elaborated.

3.8(18) explains that subtype_indications with per-object constraints
are not elaborated, but that any included expressions are evaluated.
What to do with the results of those evaluations never seems to be
explained.

3.3.1(15-20) describes the process of elaborating an object_declaration.
In step 3, per-object expressions are evaluated, but there is no
mention of elaborating anything, although later paragraph 20
does seem to imply that some sort of elaborations were supposed to
have taken place in step 3.

What should really happen is a partial elaboration of the
subtype_indication should be performed, omitting pretty much any
evaluation, and using instead the already evaluated results (either
from 3.8(18) or from the per-object evaluations just performed).
However important part of the elaboration which do need to happen
include various checks (one due to a conversion in 3.7.1(12), then
the compatibility check of 3.2.2(11)), and actually creating the
subtype.

This is described somewhat in the AARM note 3.3.1(18.a), although that
is not binding.

The elaboration of per-object constraints is mentioned in (at least)
the following other places where objects are created:

  4.3.1(19)   creating record aggregates
  4.8(10)     creating heap objects via uninitialized allocators
  9.4(14)     creating a protected object
                (This one is supposed to be redundant with, but in fact
                 appears to be inconsistent with 3.3.1.)

Strictly read, elaborating the per-object constraint would involve
reevaluating the non-per-object expressions (since there doesn't seem to
be any special definition of what happens when a per-object constraint
is elaborated), and not performing compatibility checks (since
elaboration of the subtype_indication containing the constraint doesn't
seem to be mentioned in these places).  What is wanted is the same as in
3.8(18), to finish the elaboration of the subtype_indication containing
the constraint.

-Vince Del Vecchio
vdelvecc@inmet.com

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

!from Randy Brukardt  99-08-17

Per-object constraints are mentioned in 3.8(18), 3.3.1(18), 4.3.1(19), 4.8(10),
9.1(12), 9.4(14), 9.5.2(22), 7.6(12), 7.6.1(9), and 13.14(8).
3.8(18 is the defining occurrence. The next six all deal with either the
evaluation or elaboration of per-object constraints. The other three deal with
other issues (Initialize calls, Finalize calls, and freezing, respectively)
and do not need changes.

All of 4.3.1(19), 4.8(10), 9.1(12), and 9.4(14) talk in terms of elaborating
the per-object constraint. If that was properly defined, no changes are
required in any of these clauses.

The primary problem here is with 3.3.1(18), which does not speak in terms of
elaborating the per-object constraint (meaning that needed checks aren't done).
This paragraph was changed to use that terminology.

The secondary problem is no definition of the elaboration of a per-object
constraint. This was added to 3.8(18). It also was changed to
insure that evaluation was done multiple times, if needed.

As part of the repairs, I moved the discussion of per-object constraints for
entries from 9.5.2(22) to 3.8(18), in order to insure that the same semantics
is given to both. Since this case has to be mentioned (both when defining
per-object constraint, and when defining elaboration of a per-object constraint)
leaving it in 9.5.2(22) simply means the same words have to be given a second
time. (Which increases the errors).

I noticed another problem: a discrete_subtype_definition can be a range, which
is *not* a constraint. Therefore, I added "range" to the definition of
per-object constraint (or we'd just have a new hole for the next round to
patch up).

I think that the last phrase of 3.8(18A) ("including the subtype compabilitity
check (see 3.2.2).") is redundant, but the AI recommendation seems insistent
that it be included. I'd be happy to do without it.

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

!from Randy Brukardt  99-10-06

My notes from the recent ARG meeting say that the end of the first paragraph
should be changed from:

... then the elaboration consists of the evaluation of any
included expression that is not part of a per-object expression. Each such
expression is evaluated once unless it is part of a named association in a
discriminant constraint, in which case it is evaluated once for each associated
discriminant.

to:

... then the elaboration consists of the evaluation of any
included expression that is not part of a per-object expression, according to
the rules given in 3.7.1.

I did not make this change, because the rules in 3.7.1 are wrong for this use,
unfortunately. During the meeting, I checked the behavior of existing ACATS
tests [C37213B.ADA, C37213D.ADA, and others (the tests in fact are Ada 83 tests)],
and they require that the values be evaluated but not be checked at this point.
Given that the test suite requires this behavior, and has for many years, all
compilers delay the checks, and a change would be gratuitous. However, the rules
in 3.7.1 specifically say that each value is evaluated and converted when a
discriminant is evaluated. So a reference to 3.7.1 would cause incorrect behavior.

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

Questions? Ask the ACAA Technical Agent