Version 1.9 of ais/ai-00423.txt
!standard 8.5.1(2) 05-09-29 AI95-00423/07
!standard 8.5.1(4)
!standard 8.5.4(4)
!standard 12.4(2)
!standard 12.4(5)
!standard 12.4(7)
!standard 12.4(9)
!standard 12.6(8)
!class amendment 05-03-30
!status Amendment 200Y 05-05-10
!status ARG Approved 9-0-1 05-04-18
!status work item 05-03-30
!status received 05-03-30
!priority High
!difficulty Easy
!subject Renaming, null exclusion and formal objects
!summary
(See proposal.)
!problem
At the Paris meeting, we came up with strangely inconsistent decisions
regarding the interaction of "not null" with renamings:
1 - For object renamings, we said that "not null" is not permitted under any
circumstances in the access_definition of the object_renaming_definition.
(AI95-00409)
2 - For subprogram renamings, we said that "not null" is permitted, but is
essentially ignored (like any subtype-ish property). (AI95-00404)
!proposal
It is clear that we want object renamings and subprogram renamings to be
handled consistently. However, the rules outlined in the !problem section are
not ideal because:
1 - Disallowing "not null" (the AI95-00409 option) has the peculiar consequence
that it prevents the user from "telling the truth", something that we try to
encourage. Consider:
X : not null access Integer := ...;
Y : access Integer renames X;
while Y is really of a null-excluding subtype, the user cannot write an
explicit null exclusion. This is unfortunate, as we would like them to be able
to put the "correct subtype" here.
2 - Allowing "not null" but ignoring it (the AI95-00405 option) is the Ada 83
model, but it is generally considered undesirable. If it had not be for
compatibility, modifying the rules in Ada 95 to rely on the notion of
statically matching subtypes would have been best. Since null exclusion does
not create any compatibility issue, it seems that we should "do the right
thing".
An alternative would be to always require the null_exclusion to match exactly.
We already do that for formal access types, so it would seem to be possible.
But it would cause anomolies with formal private types:
generic
type T is private;
with procedure P (A : T);
X : in out T;
procedure G is
...
type A is access ...;
procedure Q (P : not null A);
Obj : not null A;
procedure Goof is new G (T => A, P => Q, X => Obj);
--
This is annoying, because there is no way to change the specification of the
generic to allow this to work (T is not an access type, so it doesn't allow
a null exclusion).
So, the best approach seems to be to allow the user to write an explicit
null_exclusion in object and subprogram renamings, but only if such a
null_exclusion doesn't lie.
Similar rules should apply to generic subprograms.
In generic bodies we use an assume-the-worst rule to ensure that "not null"
doesn't lie.
Finally, it is curious that anonymous access types are not permitted for
generic formal objects. This is likely to make it unnecessarily hard to turn a
nongeneric package into a generic package. This restriction is lifted.
!wording
Change 8.5.1(2):
object_renaming_declaration ::=
defining_identifier : [null_exclusion] subtype_mark renames object_name;
| defining_identifier : access_definition renames object_name;
Remove the syntax rule added by AI95-00409 after 8.5.1(2/2) (that's the one
which makes a null_exclusion illegal).
Add after 8.5.1(4):
For an object_renaming_declaration with a null_exclusion or an
access_definition that has a null_exclusion:
o if the object_renaming_declaration occurs within the body of a generic unit
G or within the body of a generic unit declared within the declarative
region of the generic unit G, and the object_name denotes a generic formal
object of G, then the declaration of that formal object shall have a
null_exclusion;
o otherwise, the subtype of the object_name shall exclude null. 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.
Add after 8.5.4(4):
For a parameter or result subtype of the subprogram_specification that has
an explicit null_exclusion:
o if the subprogram_renaming_declaration occurs within the body of a generic
unit G or within the body of a generic unit declared within the declarative
region of the generic unit G, and the callable_entity_name denotes a
generic formal subprogram of G, then the corresponding parameter or
result subtype of that formal subprogram shall have a null_exclusion;
o otherwise, the subtype of the corresponding parameter or result type of the
renamed callable entity shall exclude null. 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.
Change 12.4(2) to read:
formal_object_declaration ::=
defining_identifier_list : mode [null_exclusion] subtype_mark [:=
default_expression]; |
defining_identifier_list : mode access_definition [:= default_expression];
Change 12.4(5) to read:
For a generic formal object of mode in out, the type of the actual shall
resolve to the type determined by the subtype_mark, or for a
formal_object_declaration with an access_definition, to a specific anonymous
access type. If the anonymous access type is an access-to-object type, the
type of the actual shall have the same
designated type as that of the access_definition.
If the anonymous access type is an access-to-subprogram type, the type of the
actual shall have a designated profile which is type conformant with that of
the access_definition.
Add after 12.4(7):
In the case where the type of the formal is defined by an access_definition,
the type of the actual and the type of the formal:
o shall both be access-to-object types with statically matching designated
subtypes and with both or neither being access-to-constant types; or
o shall both be access-to-subprogram types with subtype conformant designated
profiles.
For a formal_object_declaration with a null_exclusion or an access_definition
that has a null_exclusion:
o for an instantiation that occurs within the body of a generic unit G or
within the body of a generic unit declared within the declarative region of
the generic unit G, and the actual denotes a generic formal object of G,
then the declaration of that formal object shall have a null_exclusion;
o otherwise, the subtype of the actual shall exclude null. 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.
Change 12.4(9) to read: (This includes the change from AI-255)
A formal_object_declaration declares a generic formal object. The default mode
is in. For a formal object of mode in, the nominal subtype is the one denoted
by the subtype_mark {or access_definition} in the declaration of the formal.
For a formal object of mode in out, its type is determined by the subtype_mark
{or access_definition} in the declaration; its nominal subtype is nonstatic,
even if the subtype_mark denotes a static subtype; for a composite type, its
nominal subtype is unconstrained if the first subtype of the type is
unconstrained, even if the subtype_mark denotes a constrained subtype.
Add after 12.6(8):
For a parameter or result type of a formal_subprogram_declaration that has an
explicit null_exclusion:
o for an instantiation that occurs within the body of a generic unit G or
within the body of a generic unit declared within the declarative region of
the generic unit G, and the actual denotes a generic formal subprogram of
G, then the corresponding parameter or result type of that formal
subprogram shall have a null_exclusion;
o otherwise, the subtype of the corresponding parameter or result type of the
actual shall exclude null. 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.
!discussion
(See proposal.)
!example
!corrigendum 8.5.1(2)
Replace the paragraph:
object_renaming_declaration ::=
defining_identifier : subtype_mark renames object_name;
by:
object_renaming_declaration ::=
defining_identifier : [null_exclusion] subtype_mark renames object_name;
| defining_identifier : access_definition renames object_name;
!corrigendum 8.5.1(4)
Insert after the paragraph:
The renamed entity shall be an object.
the new paragraphs:
For an object_renaming_declaration with a null_exclusion or an
access_definition that has a null_exclusion:
- if the object_renaming_declaration occurs within the body of a
generic unit G or within the body of a generic unit declared within the
declarative region of the generic unit G, and the object_name
denotes a generic formal object of G, then the declaration of that formal
object shall have a null_exclusion;
- otherwise, the subtype of the object_name shall exclude null.
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.
!corrigendum 8.5.4(4)
Insert after the paragraph:
The profile of a renaming-as-declaration shall be mode-conformant with that of
the renamed callable entity.
the new paragraphs:
For a parameter or result subtype of the subprogram_specification that
has an explicit null_exclusion:
- if the subprogram_renaming_declaration occurs within the body of
a generic unit G or within the body of a generic unit declared within the
declarative region of the generic unit G, and the
callable_entity_name denotes a generic formal
subprogram of G, then the corresponding parameter or result
subtype of that formal subprogram shall have a null_exclusion;
- otherwise, the subtype of the corresponding parameter or result type
of the renamed callable entity shall exclude null. 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.
!corrigendum 12.4(2)
Replace the paragraph:
formal_object_declaration ::=
defining_identifier_list : mode subtype_mark [:= default_expression]
by:
formal_object_declaration ::=
defining_identifier_list : mode [null_exclusion] subtype_mark [:= default_expression]
| defining_identifier_list : mode access_definition [:= default_expression];
!corrigendum 12.4(5)
Replace the paragraph:
For a generic formal object of mode in out, the type of the actual shall
resolve to the type of the formal.
by:
For a generic formal object of mode in out, the type of the actual shall
resolve to the type determined by the subtype_mark, or for a
formal_object_declaration with an access_definition, to a specific
anonymous access type. If the anonymous access type is an access-to-object type,
the type of the actual shall have
the same designated type as that of the access_definition.
If the anonymous access type is an access-to-subprogram type, the type of the
actual shall have a designated profile which is type
conformant with that of the access_definition.
!corrigendum 12.4(7)
Insert after the paragraph:
For a generic formal object of mode in, the actual shall be an
expression. For a generic formal object of mode in out, the actual
shall be a name that denotes a variable for which renaming is allowed (see
8.5.1).
the new paragraphs:
In the case where the type of the formal is defined by an
access_definition, the type of the actual and the type of the formal:
- shall both be access-to-object types with statically matching
designated subtypes and with both or neither being access-to-constant types;
or
- shall both be access-to-subprogram types with subtype conformant
designated profiles.
For a formal_object_declaration with a null_exclusion or an
access_definition that has a null_exclusion:
- for an instantiation that occurs within the body of a generic unit
G or within the body of a generic unit declared within the declarative
region of the generic unit G, and the actual denotes a generic formal
object of G, then the declaration of that formal object shall have a
null_exclusion;
- otherwise, the subtype of the actual shall exclude null. 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.
!corrigendum 12.4(9)
Replace the paragraph:
A formal_object_declaration declares a generic formal object. The default
mode is in. For a formal object of mode in, the nominal subtype is the
one denoted by the subtype_mark in the declaration of the formal. For a
formal object of mode in out, its type is determined by the
subtype_mark in the declaration; its nominal subtype is nonstatic, even
if the subtype_mark denotes a static subtype.
by:
A formal_object_declaration declares a generic formal object. The default
mode is in. For a formal object of mode in, the nominal subtype is the
one denoted by the subtype_mark or access_definition in the
declaration of the formal. For a formal object of mode in out, its type
is determined by the subtype_mark or access_definition in the
declaration; its nominal subtype is nonstatic, even
if the subtype_mark denotes a static subtype; for a composite type, its
nominal subtype is unconstrained if the first subtype of the type is
unconstrained, even if the subtype_mark denotes a constrained subtype.
!corrigendum 12.6(8)
Insert after the paragraph:
The profile of the formal and actual shall be mode-conformant.
the new paragraphs:
For a parameter or result subtype of a formal_subprogram_declaration that
has an explicit null_exclusion:
- for an instantiation that occurs within the body of a generic unit
G or within the body of a generic unit declared within the declarative
region of the generic unit G, and the actual denotes a generic formal
subprogram of G, then the corresponding parameter or result type of that
formal subprogram shall have a null_exclusion;
- otherwise, the subtype of the corresponding parameter or result type
of the actual shall exclude null. 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.
!ACATS test
!appendix
****************************************************************
From: Bob Duff
Sent: Saturday, June 11, 2005 9:50 PM
AARM version 1.19.
8.5.1(4.4/2):
4.3/2 {AI95-00423-01} For an object_renaming_declaration with a null_exclusion
or an access_definition that has a null_exclusion:
4.4/2 if the object_renaming_declaration occurs within the body of a generic
unit or within the body of a generic unit declared within the
declarative region of the generic unit, and the object_name denotes a
^^^
generic formal object of that generic unit, then the declaration of that
^^^^
formal object shall have a null_exclusion;
I find this completely mystifying. I mean, how can you be "within the body of a
generic unit declared within the declarative region of the generic unit" without
simply being "within the body of a generic unit"?
What do "the" and "that" refer to, above?
I read the AARM example, and I am still not sure what this rule is
getting at.
Similar wording appears in 8.5.4(4.2/2):
4.2/2 if the subprogram_renaming_declaration occurs within the body of a
generic unit or within the body of a generic unit declared within the
declarative region of the generic unit, and the callable_entity_name
denotes a generic formal subprogram of that generic unit, then the
corresponding parameter or result type of that formal subprogram shall
have a null_exclusion;
*************************************************************
From: Pascal Leroy
Sent: Tuesday, June 14, 2005 1:34 AM
I agree that this sounds rather incomprehensible to me, and I believe that
it was extensively rewritten by Randy after the last meeting, so we'll
need to wait for his reply. (Apparently he has mail problems because I
just got 6 messages from him in the last 2 minutes.)
*************************************************************
From: Randy Brukardt
Sent: Tuesday, June 14, 2005 1:56 AM
Pascal writes:
> I agree that this sounds rather incomprehensible to me, and I believe that
> it was extensively rewritten by Randy after the last meeting, so we'll
> need to wait for his reply. (Apparently he has mail problems because I
> just got 6 messages from him in the last 2 minutes.)
Naah, I'm very productive just before going home. :-)
Actually, I had a bad mail backup because of a mailing list (not one of
mine!) that started spewing messages every minute. It just got cleared out,
and all should be fine. Of course, I'm now going to bed.
One of those six messages ought to be the reply you're looking for - wrote
it 4 hours ago.
*************************************************************
From: Randy Brukardt
Sent: Monday, June 13, 2005 9:36 PM
Bob is mystified:
> 8.5.1(4.4/2):
>
> 4.3/2 {AI95-00423-01} For an object_renaming_declaration with a
> null_exclusion
> or an access_definition that has a null_exclusion:
>
> 4.4/2 if the object_renaming_declaration occurs within the body
> of a generic
> unit or within the body of a generic unit declared within the
> declarative region of the generic unit, and the object_name
> denotes a
> ^^^
> generic formal object of that generic unit, then the
> declaration of that
> ^^^^
> formal object shall have a null_exclusion;
>
> I find this completely mystifying. I mean, how can you be "within the body of a
> generic unit declared within the declarative region of the generic unit" without
> simply being "within the body of a generic unit"?
You could be in the child of a generic unit; the child can reference the
parent's formals. I even mentioned that in the AARM note:
"The rule is so complex because it has to apply to bodies of child generics
as well."
That is, if you had a generic child Inner (now you know why the parent was
called "Outer"):
generic
package Outer.Inner is
...
end Outer.Inner;
package body Outer.Inner is
D : not null Acc_I renames Outer.B; -- Illegal.
end Outer.Inner;
> What do "the" and "that" refer to, above?
The generic unit that has the formal. The generic body may be different (if
it is a child, as above). This wording is copied from 3.10.2(32) (the
changed text), where we originally discovered this problem with
assume-the-worst rules.
> I read the AARM example, and I am still not sure what this rule is
> getting at.
The AARM example is trying to explain the need for the rule, not why it has
to be so complex.
> Similar wording appears in 8.5.4(4.2/2):
>
> 4.2/2 if the subprogram_renaming_declaration occurs within the body of a
> generic unit or within the body of a generic unit declared within the
> declarative region of the generic unit, and the callable_entity_name
> denotes a generic formal subprogram of that generic unit, then the
> corresponding parameter or result type of that formal subprogram shall
> have a null_exclusion;
And in 3.10.2(32). There, the AARM note includes:
"Declared within the declarative region of the generic" is referring to
child and nested generic units.
Perhaps I have to add that to each rename AARM note?
If you want to try to reword this, be my guest. :-) We've tried several
times to make it better, but it seems to defy improvement. It's possible
that the adaption of the wording to renames could be improved, too. Ideas
welcome.
*************************************************************
From: Randy Brukardt
Sent: Wednesday, June 15, 2005 8:39 PM
Nobody is trying to improve this wording, but no one likes it.
...
The usual way to fix such wording is to introduce a name for the unit, that
might help here because there are two different generic units involved.
4.4/2 if the object_renaming_declaration occurs within the body of a generic
unit G or within the body of a generic unit declared within the
declarative region of the generic unit G, and the object_name denotes a
generic formal object of G, then the declaration of that
formal object shall have a null_exclusion;
Does this help? (Presuming you already understand the issue with the child
units).
> > Similar wording appears in 8.5.4(4.2/2):
...
4.2/2 if the subprogram_renaming_declaration occurs within the body of a
generic unit G or within the body of a generic unit declared within the
declarative region of the generic unit G, and the callable_entity_name
denotes a generic formal subprogram of G, then the
corresponding parameter or result subtype of that formal subprogram shall
have a null_exclusion;
Better?
*************************************************************
From: Pascal Leroy
Sent: Thursday, June 16, 2005 10:25 AM
> 4.4/2 if the object_renaming_declaration occurs within the
> body of a generic
> unit G or within the body of a generic unit declared within the
> declarative region of the generic unit G, and the
> object_name denotes a
> generic formal object of G, then the declaration of that
> formal object shall have a null_exclusion;
I think it's much better.
> 4.2/2 if the subprogram_renaming_declaration occurs within
> the body of a
> generic unit G or within the body of a generic unit
> declared within the
> declarative region of the generic unit G, and the
> callable_entity_name
> denotes a generic formal subprogram of G, then the
> corresponding parameter or result subtype of that
> formal subprogram shall
> have a null_exclusion;
Much better too.
*************************************************************
Questions? Ask the ACAA Technical Agent