AI22-0041-1

!standard 7.4(6/3)                                                22-06-23  AI22-0041-1/03

!standard 7.4(7/2)

!standard 7.4(7.1/2)

!class binding interpretation 22-06-14

!status Corrigendum 1-2022 22-06-23

!status ARG Approved 15-0-0  22-06-23

!status work item 22-06-14

!status received 22-06-07

!priority Low

!difficulty Easy

!qualifier Omission

!subject Deferred constant subtype compatibility

!summary

A deferred constant should not be completed with an incompatible subtype.

!issue

The subtype given in the declaration of a deferred constant is part of the “contract” of the declaration. Clients should be able to assume that if the completion elaborates successfully, then the  value of the constant satisfies any checks (such as constraints, null exclusions, and enabled predicates) associated with that initial subtype. It is currently permitted to have a deferred constant whose initial subtype is subject to some (enabled) predicate which the completion’s subtype is not subject to and which will therefore not be checked when the completion is elaborated. This seems undesirable.

Should this example be legal? (No.)

package Bad_Deferred_Constant is
  pragma Assertion_Policy (Check);
  subtype S is String with Dynamic_Predicate => (S'Length >= 3);
  X : constant S;
private
  X : constant String := ""; -- legal?
end Bad_Deferred_Constant;

!recommendation

Require (at compile time) that the subtype used in the completion of a deferred constant shall be “statically compatible” with the subtype used in the initial declaration.

!wording

Replace 7.4(6/3) :

with:

Modify 7.4(7/2):

Delete 7.4(7.1/2) [now covered by static compatibility]:

!discussion

One could imagine dealing with this issue by somehow checking the value given in the completion of a deferred constant against both of the two subtypes. Adding complexity to the dynamic semantics of deferred constants does not seem like the right approach; better to deal with the issue statically.

Note that the definition of static compatibility includes a check for null exclusions (4.9.1(7/3)). Therefore, with this change, the rule 7.4(7.1/2) becomes redundant and we remove it as well. The requirement for static matching for constrained types could also have been removed, but that seemed like an unnecessary change that could increase the work for implementers with no real gain.

!example

(See issue.)

!corrigendum 7.4(6/3)

@drepl

@xbullet{If the deferred constant declaration includes a @fa{subtype_indication} @i{S} that defines a constrained subtype, then the constraint defined by the @fa{subtype_indication} in the full declaration shall match the constraint defined by @i{S}statically. On the other hand, if the subtype of the deferred constant is unconstrained, then the full declaration is still allowed to impose a constraint. The constant itself will be constrained, like all constants;}

@dby

@xbullet{If the deferred constant declaration includes a @fa{subtype_indication} that defines a subtype @i{S1}, then the @fa{subtype_indication} in the full declaration shall define a subtype @i{S2} that is statically compatible with @i{S1} (see 4.9.1). If @i{S1} is a constrained subtype, the constraint defined by @i{S2} shall statically match the constraint defined by @i{S1}. If the subtype @i{S1} of the deferred constant is unconstrained, then the full declaration is still allowed to impose a constraint.}

!corrigendum 7.4(7/2)

@drepl

@xbullet{If the deferred constant declaration contains the reserved word @b{aliased}, then the full declaration shall also;}

@dby

@xbullet{If the deferred constant declaration contains the reserved word @b{aliased}, then the full declaration shall also.}

!corrigendum 7.4(7.1/2)

@ddel

@xbullet{If the subtype of the deferred constant declaration excludes null, then the subtype of the full declaration shall also exclude null.}

!ACATS test

A B-test similar to the given example could be written.

!appendix

From: Randy Brukardt

Sent: Wednesday, June 15, 2022  9:27 PM

The bullet 7.4(7.1/2) is now redundant, as it is covered by static compatibility - specifically, 4.9.1(7/3). The AI has been updated to reflect this.

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