Version 1.1 of ai05s/ai05-0103-1.txt
!standard 6.5(5.2/2) 08-06-15 AI05-0103-1/01
!class binding interpretation 08-06-15
!status work item 08-06-15
!status received 06-04-25
!priority Low
!difficulty Medium
!qualifier Omission
!subject Return statements should require Static matching for all named access types
!summary
The subtype_indication in an extended_return_statement must statically match
the result type of the function if the type is an access type.
!question
We use static matching to require that null exclusions match on a function
and any extended return:
type An_Access is access Integer;
function Nice return not null An_Access is
begin
return Obj : An_Access do --
Obj := null;
end return;
end Nice;
This is because 6.5(5.2/2) requires static matching for the
subtype_indication and the result subtype if the result subtype is
constrained. An_Access is constrained as defined by 3.10(14/1).
But consider the following small change to An_Access:
type An_Access is access String;
function Nice return not null An_Access is
begin
return Obj : An_Access do --
Obj := null;
end return;
end Nice;
Now An_Access is not constrained as defined by 3.10(14/1) [the designated
subtype is an unconstrained array]. Thus the first part of 6.5(5.2/2) does
not apply, and no matching is required. So it appears that we've succeeded
in returning null from a null-excluding function. Ouch.
!wording
Modify 6.5(5.2) (as previous modified by AI05-0032-1):
If the result subtype of the function is defined by a subtype_mark, the
return_subtype_indication shall be a subtype_indication. The type of the
subtype_indication shall be covered by the result type of the function.
If the result subtype of the function is {an access type or is} constrained,
then the subtype defined by the subtype_indication shall [also be constrained
and] shall statically match this result subtype.
{Otherwise, if}[If] the result subtype of the function is unconstrained {and not
an access type}, then the subtype defined by the subtype_indication shall
be a definite subtype, or there shall be an expression.
!discussion
We require static matching for all access types, because whether or not they
are constrained depends on the designated subtype (which should match here),
and not on the characteristics of the type.
Note that 6.5(5.3/2) require static matching for all anonymous access types;
it would be strange to have a different rule for named access types.
[Should there have been an exception to both rules class-wide cases? We generally
have tried for that, but not here for some reason.]
We drop the part about the return subtype_indication being constrained, as that
is implied by static matching for non-access types (and is irrelevant and possibly
incorrect for access types).
--!corrigendum 6.5(5.2/2)
!ACATS Test
!appendix
From: Randy Brukardt
Sent: Friday, April 25, 2008 12:06 AM
Here's another one that will remind you that I'm working on ACATS tests...
We use static matching to require that null exclusions match on a function
and any extended return:
type An_Access is access Integer;
function Nice return not null An_Access is
begin
return Obj : An_Access do -- ERROR:
Obj := null;
end return;
end Nice;
This is because 6.5(5.2/2) requires static matching for the
subtype_indication and the result subtype if the result subtype is
constrained. An_Access is constrained as defined by 3.10(14/1).
But consider the following small change to An_Access:
type An_Access is access String;
function Nice return not null An_Access is
begin
return Obj : An_Access do -- OK!!
Obj := null;
end return;
end Nice;
Now An_Access is not constrained as defined by 3.10(14/1) [the designated
subtype is an unconstrained array]. Thus the first part of 6.5(5.2/2) does
not apply, and no matching is required. So it appears that we've succeeded
in returning null from a null-excluding function. That surely won't do.
Luckily, Tucker has already filled the hole: AI05-0032-1 adds "A check
is made that the value of the return object belongs to the function
result subtype.", and that clearly will fail. So at least Constraint_Error
will be raised. (Before AI05-0032-1, we would have had to return null,
as there was no check. Lovely.)
However, it is annoying that we've lost a compile-time check for a reason
that is completely unrelated to the check itself. It also means that
AARM note 6.5(5.g/3) is a lie.
Obviously, fixing the AARM note is easy; this case should be mentioned in
the AARM. But should we tweak the rules to ensure that null exclusion
checks are always made even if the access type is unconstrained (we don't
care about that for this purpose - null exclusions aren't a constraint
anyway)? In that case, the AARM note is fine (and there isn't going
to be a nasty ACATS test...)
****************************************************************
From: Robert A. Duff
Sent: Friday, April 25, 2008 7:50 AM
> Obviously, fixing the AARM note is easy; this case should be mentioned
> in the AARM. But should we tweak the rules to ensure that null
> exclusion checks are always made even if the access type is unconstrained ...
Yes.
****************************************************************
Questions? Ask the ACAA Technical Agent