CVS difference for ai05s/ai05-0035-1.txt

Differences between 1.1 and version 1.2
Log of other versions for file ai05s/ai05-0035-1.txt

--- ai05s/ai05-0035-1.txt	2007/01/13 05:25:56	1.1
+++ ai05s/ai05-0035-1.txt	2007/01/19 04:00:06	1.2
@@ -1,4 +1,7 @@
-!standard 10.2.1(15.5/2)                                      07-01-12    AI05-0035-1/01
+!standard 10.2.1(15.1/2)                                      07-01-17    AI05-0035-1/02
+!standard 10.2.1(15.4/2)
+!standard 10.2.1(15.5/2)
+!standard 10.2.1(17/2)
 !class binding interpretation 07-01-12
 !status work item 07-01-12
 !status received 07-01-12
@@ -8,15 +11,24 @@
 !subject Inconsistences with pure units
 !summary
 
+The restrictions on named access types in pure units only apply to non-derived types.
+
 The rules for pure units are enforced inside of generic units (not just inside of
 instance specifications).
 
+Subunits follow the same rules as library units for purity.
+
 Only subunits that are elaborated are required to be pure, just as in the case of
 preelaborated units.
 
 !question
+
+1 - 10.2.1(15.4-15.5/2) apply to all named access-to-object types. However, derived
+access types do not declare storage pools (they use the ones declared by the parent
+type), and thus do not cause any added state. As such, there is no reason for them
+to have checks applied. Should they be excluded from these rules? (Yes.)
 
-1 - The elaboration of generic units (as opposed to instances) does exactly nothing.
+2 - The elaboration of generic units (as opposed to instances) does exactly nothing.
 The rules 10.2.1(15.1/2-15.5/2) therefore do not apply inside of a pure generic unit.
 
 Rechecking will happen on the instance, but because the boilerplate text is not
@@ -32,7 +44,11 @@
 
 Is this hole intended? (No.)
 
-2 - AI95-0002 changes the rules in 10.2.1(11/1) to exclude some subunits of
+3 - The rules in 10.2.1(15.1/2) apply only to library items. However, 10.2.1(17/2)
+requires that all compilation units of a pure unit be pure. A subunit is a
+compilation unit, so when (if ever) is a subunit pure?
+
+4 - AI95-0002 changes the rules in 10.2.1(11/1) to exclude some subunits of
 preelaborated units to not require preelaboration.
 
 However, no corresponding change was made to pure units. The same considerations
@@ -46,47 +62,100 @@
 
 Should this rule be changed to match preelaboration? (Yes.)
 
+
 !recommendation
 
 (See Summary.)
 
 !wording
 
-1 - Add after 10.2.1(15.5/2):
+1 - Change 10.2.1(15.4/2) as follows:
 
-A generic unit is pure only if elaboration of the corresponding unit of an
-instance would not perform any such actions.
+...of a {non-derived} named access-to-variable type...
+
+Change 10.2.1(15.5/2) as follows:
+
+...of a {non-derived} named access-to-constant type...
 
-2 - Change 10.2.1(17/2) to:
+2 - Add after 10.2.1(15.5/2):
 
+A generic body is pure only if elaboration of a corresponding instance body
+would not perform any such actions.
+
+3 - Change 10.2.1(15.1/2) to:
+
+A pure compilation unit is a preelaborable compilation unit whose elaboration...
+
+2 & 4 - Change 10.2.1(17/2) to:
+
 A pragma Pure is used to declare that a library unit is pure. {The declaration and
 body of a declared pure library unit, and all subunits that are elaborated as part
 of elaborating the library unit, shall be pure. In addition, all} [If a pragma
 Pure applies to a library unit, then its[ compilation units {of a declared pure
 library unit} [shall be pure, and they] shall depend semantically only on
-compilation units of other library units that are declared pure. Furthermore,
+compilation units of other library units that are declared pure. {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.} Furthermore,
 the full view of any partial view declared in the visible part of the library
 unit that has any available stream attributes shall support external streaming (see 13.13.2). 
 
-!discussion
 
-1 - None of the rules in 10.2.1(15.1-15.5/2) depend on the properties of the
-actual type. Therefore, there is no advantage to delaying the legality checks,
-and the complication of rechecking in the instance is avoided. This is slightly
-different (but much simpler) than the preelaboration rules.
+!discussion
 
-2 - The rules for Preelaborate and Pure are supposed to be parallel to each other,
-and this is an unnecessary difference.
+1 - Derived access types always share their storage pool with their parent type.
+Thus, the properties of the pool were checked for the parent type, and no further
+checks are needed. This especially matters in generics, where we otherwise would
+need an assume-the-worst rule for derivations from formal access types in
+generic bodies. With this rule change, we don't need such a rule, and pure generic
+packages then will have fewer restrictions.
+
+2 - Given change (1), none of the rules in 10.2.1(15.1-15.5/2) depend on the
+properties of the actual parameters to an instance.
+
+Therefore, we can use a fairly simple assume-the-worst rule for generic bodies,
+and require the (re)checking be done for the instance specifications. This latter
+requires rechecking in the private part of an instance.
+
+We could have gone simpler still, and simply always make the checks on generic units. However,
+that would add restrictions to the generic specification of pure generic units that
+may not matter if the generic is always instantiated in impure contexts. Also, rechecking
+is consistent with a very similar rules for Preelaborate. It would be confusing to
+use different rules for the two categorizations, especially as pure requires
+preelaborate's restrictions to have been followed.
+
+3 - A subunit is not a library item. Thus, there is no definition for what constitutes
+a pure subunit. One option is to simply say that no subunits are pure. However, that
+would effectively ban subunits of pure units, which seems unnecessarily restrictive.
+
+It can be argued that the pure rules are intentionally designed to ignore subunits (that
+is, 10.2.1(17/2) should except subunits). However, then a package subunit of a pure
+package would not be required to be pure or even preelaborated, which would open up
+all sorts of holes.
+
+Thus, we do have to define what a pure subunit is. The easiest way is to ensure that
+the definition of pure applies to all compilation units, not just library_items.
+
+4 - The rules for Preelaborate and Pure are supposed to be parallel to each other,
+and this is an unnecessary difference. We need to make this change after fixing (2);
+this is not a real problem until (2) is fixed, as no subunits would be required
+to be pure.
 
 
 --!corrigendum A.18.2(239/2)
 
 
 !ACATS test
+
+1 - The only testable scenario would be access types derived from a formal access
+type; this generic could be instantiated in an impure context with any sort of type.
+This seems rather pathological.
 
-1 - B-Tests should be created to ensure that the checks are made in the generic unit.
+2 - B-Tests should be created to ensure that the checks are made in the generic unit.
 
-2 - A C-Test should ensure that a package subunit of a pure subprogram does not need
+3 - A B-Test should ensure that pure restrictions are enforced in a package subunit of
+a pure package.
+
+4 - A C-Test should ensure that a package subunit of a pure subprogram does not need
 to be pure.
 
 !appendix
@@ -178,7 +247,182 @@
 
 ****************************************************************
 
+From: Pascal Leroy
+Date: Monday, January 15, 2007  2:11 AM
+
+> Well, while I agree with your explanation, now I have a new 
+> worry, having moved on to Pure.
+> 
+> Following this explanation, none of the extra Pure restrictions of
+> 10.2.1(15.1-15.4/2) would enforced inside of a generic 
+> template. Moreover,
+> 10.2.1(17/2) does not have the wording to enforce them in a 
+> private part. And there is no generic special cases for Pure 
+> like there are for Preelaborate. Therefore, I must conclude 
+> that they're never enforced for the private part and body of 
+> generic units.
+
+I agree.  Note that it all goes back to the original Ada 95: while there
+were rules for preelaboration, there has never been anything for purity.
+Strange.
+
+> (1) Add the boilerplate to 10.2.1(17/2) so that the 
+> additional Pure rules are rechecked in the private part;
+
+Correct.
+
+> (2) Add after 10.2.1(15.6/2) something like:
+> 
+> A generic_body is pure only if elaboration of a corresponding 
+> instance body would not perform any such actions.
+> 
+> [We don't need any "presuming that"s, because 15.2-5/2 don't 
+> depend on the properties of the types involved, other than 
+> that it is access type.]
+
+I don't think that's true.  It seems to me that 10.2.1(15.4/2-15.5/2)
+effectively depend on whether the actual for a formal access type has
+storage size 0.  Consider:
+
+	generic
+	   type AV is access Integer;
+	   type AC is access constant Boolean;
+	package G is
+	   pragma Pure (G);
+	end G;
+
+	package body G is
+	   type DAV is new AV; -- Legal?  Depends on the storage size of AV.
+	   type DAC is new AC; -- Legal?  Depends on the storage size of AC.
+	end G;
+
+Obviously we want the declarations of DAV and DAC to be illegal, but we
+need an explicit rule to say so.  And you cannot say "a formal access type
+is defined to have storage size 0", because that would make allocators for
+such types illegal everywhere.
+
+> I'll make another AI for this one. Sigh.
+
+Yes, we have to.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Monday, January 15, 2007  5:53 PM
+
+> I don't think that's true.  It seems to me that 10.2.1(15.4/2-15.5/2)
+> effectively depend on whether the actual for a formal access type has
+> storage size 0.  Consider:
+
+Do we have to?? ;-)
+ 
+> 	generic
+> 	   type AV is access Integer;
+> 	   type AC is access constant Boolean;
+> 	package G is
+> 	   pragma Pure (G);
+> 	end G;
+> 
+> 	package body G is
+> 	   type DAV is new AV; -- Legal?  Depends on the storage size of AV.
+> 	   type DAC is new AC; -- Legal?  Depends on the storage size of AC.
+> 	end G;
+
+No, I never thought of deriving from a formal access type, it's not exactly
+something that you would normally want to do.
+
+<grumble>
+Why the heck do we even allow derived access types? What could they possibly
+be useful for? Usually, we want less type checking with access types, not more.
+Sigh.
+</grumble>
+
+> Obviously we want the declarations of DAV and DAC to be illegal, but we
+> need an explicit rule to say so.  And you cannot say "a formal access type
+> is defined to have storage size 0", because that would make allocators for
+> such types illegal everywhere.
+
+Yes, "presuming that any formal access types have a non-zero storage size
+specified." 
+
+> > I'll make another AI for this one. Sigh.
+> 
+> Yes, we have to.
+
+Long done. And now redone.
+
+****************************************************************
+
+From: Tucker Taft
+Date: Monday, January 15, 2007  6:46 PM
+
+Unless I am missing something (which is entirely possible)
+I don't understand why we "obviously" want DAV and DAC to
+be illegal.  Declaring a derived access type has no
+particular effect, from the point of view of storage
+pools.  It is little more than a renaming or a subtype
+declaration.  We should only disallow declaring
+non-derived access types with non-zero storage pools.
+There is never any harm in declaring derived access types.
+
+****************************************************************
+
 From: Randy Brukardt
+Date: Monday, January 15, 2007  7:42 PM
+
+Well, we're discussing how the existing rules should be implemented
+in generic bodies. We weren't discussing whether those rules were
+too broad. It surely doesn't make sense to have different rules in
+generic bodies than in the rest of the Ada universe.
+
+Now, I suppose you could argue that the existing rules are broader
+than they need to be, and it is just as easy to change that rather
+than fix the generic body bugs. But we're in bug fixing mode now, not
+redesign the language mode. It would be easier still (and just as useful)
+to replace 10.2.1(15.1/2-18/2) entirely with "pragma Pure is a synonym
+for pragma Preelaborate"! ;-)
+
+****************************************************************
+
+From: Tucker Taft
+Date: Monday, January 15, 2007  10:59 PM
+
+I think both 10.2.1(15.4) and 10.2.1(15.5) should talk
+only about non-derived access types.  I think it was
+just an oversight that derived access types got lumped into this
+restriction, since derived access types never create
+a new storage pool.  I can believe you are frustrated,
+but this seems like a pretty straightforward goof, and it
+happens to solve Pascal's contract model problem.
+
+****************************************************************
+
+From: Pascal Leroy
+Date: Wednesday, January 17, 2007  8:42 AM
+
+I agree with Tuck.
+
+The fix is probably to add "nonderived" to 10.2.1(15.4/2-15.5/2).
+
+I agree that we are in bug fixing mode, but we clearly have a bug here (we
+need to say something about generic bodies) and either we invent
+convoluted rules for generic bodies, or we add "nonderived" in two places.
+I certainly prefer the latter.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Wednesday, January 17, 2007  12:32 PM
+
+OK, but remember that we still need the rules for generic bodies, they're
+just a bit less convoluted. Because we surely want to prohibit variables
+in pure generic bodies, and that's not true currently. The net effect is
+that one bug (generic bodies aren't checked) has turned into three. C'est la
+vie.
+
+***************************************************************
+
+From: Randy Brukardt
 Date: Friday, January 12, 2007  8:45 PM
 
 You'd think I was getting paid by the number of holes I find...
@@ -194,6 +438,79 @@
 pure? I don't think so; it's not elaborated by the elaboration of the pure subprogram.
 
 I'll add that to the other pure issue.
+
+****************************************************************
+
+From: Pascal Leroy
+Date: Monday, January 15, 2007  3:57 AM
+
+I'm not sure if there is actually a real problem here, although surely the
+fact that the wording is different is puzzling.
+
+First, note that 10.2.1(5) talks about "construct" while 10.2.1(15.1/2)
+talks about "library_item".
+
+Because of the wording of 10.2.1(5), a package subunit of a preelaborable
+subprogram may be non-preelaborable.  But since it is actually not
+elaborated when the enclosing subprogram is elaborated, we need the second
+sentence of 10.2.1(11/1) to say "well, a subunit may well be
+non-preelaborable but it's OK if it's not elaborated when the library unit
+gets elaborated".
+
+On the other hand, 10.2.1(15.1/2) is worded in terms of what happens when
+the library_item get elaborated (and that seems much more sensible than
+worrying about the elaboration of arbitrarily nested constructs).  Surely
+when a library subprogram get elaborated any package subunit that it may
+contain *doesn't* get elaborated, so none of the actions of
+10.2.1(15.2/2-15.5/2) take place (at least, not because of the subunit).
+
+From which I conclude that the RM is correct but unnecessarily obscure.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Monday, January 15, 2007  5:31 PM
+
+> First, note that 10.2.1(5) talks about "construct" while 10.2.1(15.1/2)
+> talks about "library_item".
+
+Good point. But that means none of this applies to a subunit (which is never
+a library item).
+
+> Because of the wording of 10.2.1(5), a package subunit of a preelaborable
+> subprogram may be non-preelaborable.  But since it is actually not
+> elaborated when the enclosing subprogram is elaborated, we need the second
+> sentence of 10.2.1(11/1) to say "well, a subunit may well be
+> non-preelaborable but it's OK if it's not elaborated when the library unit
+> gets elaborated".
+
+Right.
+ 
+> On the other hand, 10.2.1(15.1/2) is worded in terms of what happens when
+> the library_item get elaborated (and that seems much more sensible than
+> worrying about the elaboration of arbitrarily nested constructs).  Surely
+> when a library subprogram get elaborated any package subunit that it may
+> contain *doesn't* get elaborated, so none of the actions of
+> 10.2.1(15.2/2-15.5/2) take place (at least, not because of the subunit).
+
+OK, but what happens for a package subunit of a pure package?
+
+10.2.1(17/2) says "... then its compilation units shall be pure". Surely a
+subunit is a compilation unit, but it is not a library_item. Thus, I could
+conclude that a pure package cannot have subunits at all.
+
+Surely, we want package subunits of a pure package to be pure and preelaborated.
+(That is, the rules need to be enforced.) But if we just fix the language to make
+that true, then we catch package subunits of a pure subprogram.
+
+The easiest way to do that is to adopt the AI-2 language, and fix 10.2.1(15.1/2)
+to say "compilation unit" rather than "library_item". I'm sure there is another
+way to do it, but why try to work out something from scratch? It's necessarily
+going to be wrong.
+ 
+> From which I conclude that the RM is correct but unnecessarily obscure.
+
+Sorry, we're not going to get off that easily. ;-)
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent