Version 1.6 of ai05s/ai05-0102-1.txt
!standard 3.7(16) 09-10-12 AI05-0102-1/04
!standard 3.7.1(9)
!standard 6.4.1(6)
!standard 8.6(27/2)
!class binding interpretation 08-06-15
!status Amendment 201Z 09-06-27
!status WG9 Approved 09-11-05
!status ARG Approved 7-0-0 09-06-13
!status work item 08-06-15
!status received 06-04-24
!priority Low
!difficulty Medium
!qualifier Omission
!subject Some implicit conversions ought to be illegal
!summary
A legality rule is added to 8.6 to ensure that all implicit conversions
are between types that are convertible.
!question
Consider the following:
declare
VObj : access Designated := ...;
CObj : access constant Designated := ...;
Cnst : aliased constant Designated := ...;
begin
VObj := Cnst'access; --
VObj := CObj; --
end;
(1) is illegal by 3.10.2(25).
Surely we want (2) to be illegal, too, but there doesn't seem to be any
rule that covers it.
!wording
Delete 3.7(16), 3.7.1(9), and 6.4.1(6).
Add after 8.6(27/2):
If the expected type of a construct is T1 and the actual type of the construct
is T2, then T2 shall be convertible to T1 (see 4.6).
AARM Reason: This is needed to prevent implicit conversions which would be
illegal if they were explicit conversions. For instance, we do not want
to implicitly convert an access-to-constant value to an anonymous
access-to-variable type. We do not want to make the resolution rules
specific enough to prevent these sorts of issues, so we need a separate
legality rule.
!discussion
5.2 has no legality rule that applies in this case. The closest we have
is 5.2(11), which is a dynamic semantics rule, and it is uncomfortable
to have legality depending on a dynamic rule. Thus, a new legality rule
is needed somewhere.
4.6 defines the term "convertible" for rules like this. Indeed, some
implicit conversion contexts (3.7, 3.7.1, and 6.4.1) already have legality
rules. This was an Ada 95 attempt to fix this problem; these are the only
places where mismatches were possible in Ada 95. (Ada 95 ultimately did not
have this problem, as resolution did not allow an access-to-constant value
to match an anonymous access type. But that will not work for Ada 2005, as
we now have anonymous access-to-constant types.)
We could try a similar fix for Ada 2005. However, the index lists more than
30 places that use implicit conversion, and it would be silly to add legality
rules in that many more places. Besides the sheer volume of change, there would
be a lingering maintenance problem where any new implicit conversion contexts
could easily forget to add the needed legality rule.
Implicit conversion is implicitly defined in 8.6 (by the definition of
which types match an expected type T). So that seems to be the best
place for a blanket legality rule.
The three existing rules (3.7(16), 3.7.1(9), and 6.4.1(6)) are then removed,
as there is no value to having special rules in 3 out of more than 30 cases.
The new rule should be indexed to "implicit conversion, legality" and to
"convertible (required)" (the latter to match the existing rules).
!corrigendum 3.7(16)
Delete the paragraph:
The type of the default_expression, if any,
for an access discriminant shall be convertible to the anonymous access type of
the discriminant (see 4.6).
!corrigendum 3.7.1(9)
Delete the paragraph:
The expression associated with an access
discriminant shall be of a type convertible to the anonymous access type.
!corrigendum 6.4.1(6)
Delete the paragraph:
The type of the actual parameter associated with an access parameter
shall be convertible (see 4.6) to its anonymous access type.
!corrigendum 8.6(27/2)
Insert after the paragraph:
When a construct is one that requires that its expected type be a single type
in a given class, the type of the construct shall be determinable solely from the
context in which the construct appears, excluding the construct itself, but using
the requirement that it be in the given class.
Furthermore, the context shall not be one that expects any type in some class that
contains types of the given class; in particular, the construct shall not be the
operand of a type_conversion.
the new paragraph:
If the expected type of a construct is T1 and the actual type of the construct
is T2, then T2 shall be convertible to T1 (see 4.6).
!ACATS Test
An ACATS test should check that implicit conversions like the one in the
question are illegal.
!appendix
From: Randy Brukardt
Sent: Thursday, April 24, 2008 10:01 PM
Can an implicit subtype conversion be illegal (not just raise an exception)?
Channeling Adam, I'm not sure. (I am sure what answer we want, so the only
question is whether the Standard actually justifies that answer.)
Consider the following from an ACATS test now under construction:
declare
VObj : access Designated := ...;
CObj : access constant Designated := ...;
Cnst : aliased constant Designated := ...;
begin
VObj := Cnst'Access; -- ERROR: (1)
VObj := CObj; -- ERROR: (2)
end;
While I'm certain that we want (2) to be illegal, I'm having trouble justifying
it based on the wording of the Standard.
(1) resolves because the type of the access attribute is that of the expected
type; but it is illegal because it violates 3.10.2(25).
(2) resolves because of 8.6(25/2), which allows these otherwise different types
to match. So no error there. We turn to 5.2's Legality Rules. 5.2(5/2) is
satisfied because the target is a variable. 5.2(6) doesn't apply (VObj isn't
tagged). So why is this illegal?
The only hope resides in the Dynamic Semantics rules, which is not a likely
place to look for rules that make things illegal! The rule is 5.2(11): the value
is converted to the subtype of the target. One can then say that the legality
rule 4.6(24.12/2) applies. But this is weird, because (a) it mentions the
possibility of an exception, but not illegality; (b) it's not clear if the
original type of the value is considered or not; (c) it's not clear that
an actual *type* conversion is possible. (Yes, I know that there are no
named types in Ada [everything is a subtype], but these aren't named anyway... :-).
I think we should at least have a To Be Honest note in the AARM that this
implicit subtype conversion can be illegal in cases involving anonymous types,
and it can convert types, not just subtypes, in such cases. It would be better
for there to be an explicit statement of that fact somewhere (it probably isn't
practical to put it everywhere that it can happen: there is a half a column of
references for "implicit subtype conversion" in the RM's index; but the
assignment case is the most common one).
Do I have the intent right here, or have I missed something??
****************************************************************
From: Robert A. Duff
Sent: Friday, April 25, 2008 7:47 AM
> The only hope resides in the Dynamic Semantics rules, which is not a
> likely place to look for rules that make things illegal!
Indeed, we can't use Dynamic Semantics to say something is illegal!
Implicit things being illegal seems uncomfortable anyway. Seems like we're
missing a rule.
The fact that converting to a subtype can convert the type as well is not new.
It is used for example in the semantics of calls to inherited subprograms.
4.6(58) seems relevant:
58 Conversion to a type is the same as conversion to an unconstrained
subtype of the type.
58.a Reason: This definition is needed because the semantics of various
constructs involves converting to a type, whereas an explicit
type_conversion actually converts to a subtype. For example, the
evaluation of a range is defined to convert the values of the
expressions to the type of the range.
****************************************************************
Questions? Ask the ACAA Technical Agent