Version 1.5 of ai05s/ai05-0026-1.txt

Unformatted version of ai05s/ai05-0026-1.txt version 1.5
Other versions for file ai05s/ai05-0026-1.txt

!standard 7.6(9.4/2)          08-04-09 AI05-0026-1/04
!standard B.3.3(9/2)
!standard B.3.3(10/2)
!class binding interpretation 06-11-13
!status WG9 Approved 08-06-20
!status ARG Approved 8-0-2 06-11-09
!status work item 06-11-13
!status received 06-11-03
!priority Medium
!difficulty Easy
!qualifier Omission
!subject Missing rules for Unchecked_Unions
!summary
A variant component of an Unchecked_Union type cannot have a type that needs finalization.
!question
1 - B.3.3(10/2) says that "A component declared in a variant_part of an unchecked union type shall not have a controlled, protected, or task part". This rule is wildly privacy-violating. Why don't we just assume the worst for private types (and private extensions)? Of course, for generics we would need the usual rigmarole of assuming-the-worst in the body and rechecking in the specification.
2 - The !proposal of AI95-00216 explains that "it is illegal to mention a discriminant explicitly in a component clause", which seems like a good idea. There appears to be no rule that has that effect. So is it just that we forgot to put the rule in the wording?
!recommendation
(See Summary.)
!wording
Insert after 7.6(9.4/2)
- it is a partial view whose full view needs finalization; or
Replace B.3.3(9/2)
Any name that denotes a discriminant of an object of an unchecked union type shall occur within the declarative region of the type.
with
Any name that denotes a discriminant of an object of an unchecked union type shall occur within the declarative region of the type, and shall not occur within a record_representation_clause.
Replace B.3.3(10/2)
A component declared in a variant_part of an unchecked union type shall not have a controlled, protected, or task part.
with
The type of a component declared in a variant_part of an unchecked union type shall not need finalization. In addition to the places where Legality Rules normally apply (see 12.3), this rule also applies in the private part of an instance of a generic unit. For an unchecked union type declared within the body of a generic unit, or within the body of any of its descendant library units, no part of the type of a component declared in a variant_part of the unchecked union type shall be of a formal private type or formal private extension declared within the formal part of the generic unit.
!discussion
The 7.6 addition is needed in order to make it clear that the definition of "needs finalization" looks through privacy. In a "static semantics" section, privacy is respected by default; if we want to ignore privacy, then this must be stated explicitly.
The addition to B.3.3(9/2) is in response to the second part of the question; a component_clause can only be used as part of a record_representation_clause.
It is intended that the new 10/2 formulation be equivalent (for purposes of Legality Checking of Unchecked_Union pragmas) to changing the definition of "needs finalization" to conservatively assume within a generic body that a generic formal private type or private extension "needs finalization".
We don't actually make this change because that would interact badly with the rules for the No_Nested_Finalization restriction. We want to treat generic formal types conservatively in one case but not the other because No_Nested_Finalization restriction checking is a post-compilation check while legality checking for an Unchecked_Union pragma is not.
The requirement of B.3.3(7/2) that "All component subtypes of an unchecked union type shall be C-compatible" typically eliminates 99% of the problems in this area anyway, but we don't want to rely on that.
It is intended that this wording should handle the case of a formal private type (or a formal private extension) of a formal package. Consider this example:
declare generic type T is private; package G1 is end G1;
generic with package I1 is new G1 (<>); package G2 is end G2;
package body G2 is type U_U (D : Boolean) is record case D is when False => null; when True => F : I1.T; end case; end record; pragma Unchecked_Union (U_U); end G2; begin null; end;
The pragma should be rejected even if the implementation is willing to permit I1.T as a C-compatible type (using the freedom granted by B.1(20)).
!corrigendum 7.6(9.4/2)
Insert after the paragraph:
the new paragraph:
!corrigendum B.3.3(9/2)
Replace the paragraph:
Any name that denotes a discriminant of an object of an unchecked union type shall occur within the declarative region of the type.
by:
Any name that denotes a discriminant of an object of an unchecked union type shall occur within the declarative region of the type, and shall not occur within a record_representation_clause.
!corrigendum B.3.3(10/2)
Replace the paragraph:
A component declared in a variant_part of an unchecked union type shall not have a controlled, protected, or task part.
by:
The type of a component declared in a variant_part of an unchecked union type shall not need finalization. In addition to the places where Legality Rules normally apply (see 12.3), this rule also applies in the private part of an instance of a generic unit. For an unchecked union type declared within the body of a generic unit, or within the body of any of its descendant library units, no part of the type of a component declared in a variant_part of the unchecked union type shall be of a formal private type or formal private extension declared within the formal part of the generic unit.
!ACATS test
!appendix

From: Pascal Leroy
Date: Monday, October 23, 2006  9:15 AM

Three questions on pragma Unchecked_Union.

1 - B.3.3(10/2) says that "A component declared in a variant_part of an
unchecked union type shall not have a controlled, protected, or task
part".  This rule is wildly privacy-violating.  Why don't we just assume
the worst for private types (and private extensions)?  Of course, for
generics we would need the usual rigmarole of assuming-the-worst in the
body and rechecking in the specification.

2 - The !proposal of AI95-00216 explains that "it is illegal to mention a
discriminant explicitly in a component clause", which seems like a good
idea.  However I can't find a rule that would have that effect.  I can't
find anything in the minutes that would indicate that we changed our mind.
So is it just that we forgot to put the rule in the wording?

3 - B.3.3(9/2) says that "Any name that denotes a discriminant of an
object of an unchecked union type shall occur within the declarative
region of the type".  I am not too sure what "a discriminant of an object"
means.  Consider an aggregate in named notation like (D => 2, C => 3.14).
I would naively think that the name D denotes the discriminant of the
(anonymous) object for the aggregate.  In this case, the above-mentioned
rule would make the aggregate illegal, which would be obnoxious.

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

From: Robert Dewar
Date: Monday, October 23, 2006  9:20 AM

> 1 - B.3.3(10/2) says that "A component declared in a variant_part of an
> unchecked union type shall not have a controlled, protected, or task
> part".  This rule is wildly privacy-violating.  Why don't we just assume
> the worst for private types (and private extensions)?  Of course, for
> generics we would need the usual rigmarole of assuming-the-worst in the
> body and rechecking in the specification.

So what? Unchecked_Union should be regarded only as a way of interfacing
to C, and C has none of this junk. Yes, I know a lot of junk has crept
in already that is not C related. I objected strongly to Tuck's over-
generalization here, but let's not make it even worse. The idea of
unchecked unions of tasks and controlled types is truly horrible :-)

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

From: Tucker Taft
Date: Monday, October 23, 2006  10:01 AM

> 1 - B.3.3(10/2) says that "A component declared in a variant_part of an
> unchecked union type shall not have a controlled, protected, or task
> part".  This rule is wildly privacy-violating.  Why don't we just assume
> the worst for private types (and private extensions)?  Of course, for
> generics we would need the usual rigmarole of assuming-the-worst in the
> body and rechecking in the specification.

Unchecked union is similar to a representation clause,
so privacy breaking doesn't seem too bad.  In some ways
it would seem worse to disallow all private types from
unchecked unions.  I suppose we only need to disallow
private types whose full type is not visible immediately
within the scope where the unchecked-union type is defined.
That is probably adequate, since if you really need
an unchecked-union containing a private type, you can define
it in the same scope where the private type is defined.

> 2 - The !proposal of AI95-00216 explains that "it is illegal to mention a
> discriminant explicitly in a component clause", which seems like a good
> idea.  However I can't find a rule that would have that effect.  I can't
> find anything in the minutes that would indicate that we changed our mind.
> So is it just that we forgot to put the rule in the wording?

Seems plausible.  ;-)

> 3 - B.3.3(9/2) says that "Any name that denotes a discriminant of an
> object of an unchecked union type shall occur within the declarative
> region of the type".  I am not too sure what "a discriminant of an object"
> means.  Consider an aggregate in named notation like (D => 2, C => 3.14).
> I would naively think that the name D denotes the discriminant of the
> (anonymous) object for the aggregate.  In this case, the above-mentioned
> rule would make the aggregate illegal, which would be obnoxious.

That was certainly not the intent.  I would say that a use of a
selector_name in an aggregate does *not* denote the discriminant
of an *object*.  It denotes the declaration of the discriminant.
I believe that we should interpret "name that denotes a discriminant
of an object" as a name that is used in a context where it
is interpreted as the name of a value or an object, such as
in an expression context, or as the prefix of a larger name.

Or even simpler, if you look at the syntactic category "name"
it does *not* include "selector_name."  So the "D" in your
aggregate above is not a "name" at all, in the sense that it
is not of the syntactic category "name."  (This is reminiscent
of the fact that a "generic package" is not a "package" despite
lexicographic appearances to the contrary.)

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

From: Pascal Leroy
Date: Tuesday, October 24, 2006  2:50 AM

> Unchecked union is similar to a representation clause,
> so privacy breaking doesn't seem too bad.

I hate privacy breaking, in part because it's hard to implement in our
technology.  But if we have to have a privacy breaking in this case, I
would argue that it should say "needs finalization" (which is already
privacy-breaking, being related to restrictions).  There is no point in
forcing compilers to compute a slightly different predicate for this
particular rule.

Not to mention that we would still need a specific assume-the-worst rule
for generic formal types.

> In some ways
> it would seem worse to disallow all private types from 
> unchecked unions.  I suppose we only need to disallow private 
> types whose full type is not visible immediately within the 
> scope where the unchecked-union type is defined. That is 
> probably adequate, since if you really need an 
> unchecked-union containing a private type, you can define it 
> in the same scope where the private type is defined.

Unfortunately that's not quite true.  There is an IA recommending that
System.Address be a private type (13.7(37)).  Having a C union containing
an address doesn't seem unreasonable.  But I don't think we want to force
users to declare such unions in children of System...

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

From: Pascal Leroy
Date: Tuesday, October 24, 2006  2:55 AM

> The idea of unchecked unions of 
> tasks and controlled types is truly horrible :-)

It is, but now that we have this rule in the RM it should be well-defined,
and implementers should know what to do with private types.  Only the
mildly insane would want to put tasks in unchecked unions, but as I
mentioned in a previous message, there is at least one private type which
is of interest here, and that's System.Address.  I want to know if an
unchecked union with an address in it is legal or not (I realize that
Dewar's rule says "of course, how could anyone think otherwise").

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

From: Robert Dewar
Date: Tuesday, October 24, 2006  6:26 AM

Indeed System.Address is probably the MOST useful type in an unchecked
union, so that must indeed work.

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

From: Robert Dewar
Date: Tuesday, October 24, 2006  7:03 AM

> Unfortunately that's not quite true.  There is an IA recommending that
> System.Address be a private type (13.7(37)).  Having a C union containing
> an address doesn't seem unreasonable.  But I don't think we want to force
> users to declare such unions in children of System...

System.Address must be allowed in unchecked unions, and of course we 
can't require such unions to be in children of System (which may not 
even be allowed in some implementations.

So this must work by the Dewar rule, and if it is necessary to fix
the RM to allow this, it must be fixed, hopefully without dragging
more horrible irrelevant junk into unchecked union.

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


Questions? Ask the ACAA Technical Agent