AI22-0076-3
!standard 3.2.1(5) 26-07-14 AI22-0076-3/01
!standard 4.5.2(4.1/5)
!standard 4.8(5.5/3)
!class Amendment 26-07-14
!status work item 26-07-14
!status received 23-06-05
!assigned author Steve Baird and Tucker Taft
!submitter Tucker Taft
!priority High
!difficulty Hard
!subject Static accessibility checking
Define legality checks for "pragma Strict_Static_Checks (Accessibility_Check);"
Pragma Strict_Static_Checks (defined in AI22-0165-1) takes a check as an argument and imposes additional legality rules with the general goal of ensuring that any associated run-time checks cannot possibly fail. Additional legality rules are enforced, typically in order to replace a possible run-time error with a compile-time error.
Those additional legality rules need to be defined for each check.
In particular, they need to be defined for Accessibility_Check. That is the topic of this AI.
This AI depends on AI22-0165-1.
In many cases, a dynamic accessibility check is accompanied in the RM by a corresponding legality rule disallowing cases where the run-time check would be guaranteed to fail (usually these include the phrase "shall not be statically deeper"). If strict static checking[a][b] of accessibility checks is in effect, then those existing legality rules are extended so that instead of disallowing only the case where failure of the corresponding run-time check is guaranteed, the case where success is not guaranteed is also disallowed. In some cases, this is accomplished by treating entities whose accessibility level is not normally known statically (e.g., the anonymous type of an access parameter, the type of a standalone object of an anonymous access-to-object type) as having a conservatively-chosen known accessibility level for purposes of these existing legality rules.
[Note: before reviewing this wording in detail, please read !discussion][c]
Insert after 4.8(5.5/3):
If strict static checking of accessibility checks is in effect (see ???) then the type of the allocator shall not be an anonymous access type.[d]
Insert after 4.5.2(4.1/5):
If strict static checking of accessibility checks is in effect (see ???), then for a membership test where the tested type is a general access-to-object type, the accessibility level of the access type shall be the same as or statically deeper than the accessibility level of the type of the tested_simple_expression.
AARM note: This disallows the case where the result of a membership test depends on a dynamic accessibility test.
Insert after 3.2.1(5)
If strict static checking of accessibility checks is in effect (see ???), then a composite type shall not have a component subtype that is an unconstrained subtype of a type having an access discriminant
AARM note: This rule is not redundant if the access discriminant has a default value.[e]
Insert after 7.3(12):
If strict static checking of accessibility checks is in effect (see ???) and a partial view has neither known nor unknown discriminants and the full_type_declaration defines a type that has an access
discriminant, then the full type_type_declaration shall define a constrained subtype.
AARM note: This rule is not redundant if the access discriminant has a default value.
Insert after 12.5.1(6/5):
If strict static checking of accessibility checks is in effect (see ???) and a formal private or derived type lacks discriminants (known or unknown) then the corresponding actual parameter in an instantiation shall not be an unconstrained subtype of a type that has an access discriminant.
AARM note: This rule is not redundant if the access discriminant has a default value.
Insert after 3.10.2(21.1/5):
If strict static checking of accessibility checks is in effect (see ???) then, notwithstanding other rules given above:
Insert after 6.4.1(6.4/3):
If strict static checking of accessibility checks is in effect (see ???) then when calling a function that has both an access parameter and an access result type, the accessibility level of the type of the corresponding actual parameter shall not be statically deeper than that of the master of the call (see 3.10.2).
AARM Note: This rule could apply in a call to the following (legal) function:
function Identity (X : access T) return access T is (X);
Insert after 6.4(9.b):
A function is said to *depend on the master of the call* if the result type is either an anonymous access type, a type that has one or more access discriminants, a class-wide type, or a type with unknown discriminants.
Legality Rules
If strict static checking of accessibility checks is in effect (see ???) then in the case of a call to a function that depends on the master of the call, the level of the master of the call shall be the same as or statically deeper than that of the called function.
Insert after 3.9.1(4.m/2):
If strict static checking of accessibility checks is in effect (see ???) and the accessibility level of a tagged type is statically deeper than that of its parent type, or of a progenitor, then no primitive operation inherited from that parent or progenitor (whether overridden or not) shall have an anonymous access type as either a formal parameter type or as a function result type.
Insert after 6.5(5.d.1/3):
If strict static checking of accessibility checks is in effect (see ???) and a return statement applies to the body of a function that depends on the master of the call (see 6.4), then the level of the master of the call is considered (for purposes of the preceding legality rules) to be that of the function.
This AI is currently missing something that is quite essential. We never use all of this additional compile time checking to define any of the RM-defined dynamic accessibility checks as being "known to succeed" (using terminology of AI22-0165-1). So this AI, as it stands, would cause lots of valid code to become illegal. Fixing this is somewhat complicated because in some cases we rely on enforcement of the new compile-time checks defined in this AI in, for example, other units. For example, prohibiting certain calls to a given subprogram may be needed to guarantee that an accessibility check within that subprogram will succeed. So further work is needed.
This AI has several uses of the wording
If strict static checking of accessibility checks is in effect (see ???)
This is just a placeholder. Perhaps AI22-0165-1 will define some term something like
A given check is said to be statically checked for a given entity or at the point of a given construct if ...
so that we can instead say something like (for example)
If Accessibility_Check is statically checked for an allocator, then the type of the allocator shall not be an anonymous access type.
The rules about "mixed" cases (where strict static checking for some given check is in effect for some but not all of the units of a partition) are not specified separately for each check, but rather as part of the check-independent portion of the definition of pragma Strict_Semantic_Checking.
So no discussion of such scenarios here.
Just for the record, a previous version of this AI (where we instead defined a restriction, No_Dynamic_Accessibility_Checking) included the following rules:
[a]Why are you limiting this to strict static checking? Regular static checking would seem to benefit from it as well (especially as compilers could remove additional dynamic checks, making more code legal).
[b]I agree, we should only say "static checking" and probably use the check name Accessibility_Check explicitly. And I think based on AI22-0165-1, you can safely say "(see 11.5)".
[c]I added this note because I wasted time critiquing the wording when the !discussion makes clear this is not anticipated to be the final form of the wording.
[d]For each of these restrictions that are *not* tied in any obvious way to specific dynamic Accessibility_Checks, it would be nice to see some reason for the restriction, at least in the !discussion, or perhaps summarized in an AARM note.
[e]Why would I think it is redundant? Usually, one documents the reason why a rule might be redundant.