CVS difference for ais/ai-00366.txt
--- ais/ai-00366.txt 2005/06/16 23:47:35 1.15
+++ ais/ai-00366.txt 2005/08/21 06:00:34 1.16
@@ -1,9 +1,10 @@
-!standard 10.2.1(16) 05-06-08 AI95-00366/09
+!standard 10.2.1(16) 05-08-07 AI95-00366/10
!standard 3.2(6)
!standard 3.8(9)
+!standard 4.8(5)
!standard 10.2.1(17)
!standard 10.2.1(18)
-!standard 13.13.2(1/1)
+!standard 13.13.2(36/1)
!standard E.2.2(8)
!standard E.2.2(14/1)
!standard E.2.2(17/1)
@@ -79,6 +80,21 @@
Note for Corrigendum: "component" is incorrectly italicised in 3.8(9).
+Added after 4.8(5):
+
+ An allocator shall not be of an access type for which the
+ Storage_Size has been specified by a static expression with value
+ zero or is defined by the language to be zero. 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. This rule does not apply in the body of a generic unit or within
+ a body declared within the declarative region of a generic unit, if the
+ type of the allocator is a descendant of a formal access type declared
+ within the formal part of the generic unit.
+
+ AARM NOTE: The last sentence covers the case of children of generics, and
+ formal access types of formal packages of the generic unit.
+
Replace 10.2.1(16)
A pure library_item is a preelaborable library_item that does not
contain the declaration of any variable or named access type, except
@@ -86,14 +102,49 @@
by:
- A pure library_item is a preelaborable library_item that does not
- contain the declaration of any variable, or named access-to-object
- type for which the Storage_Size has not been specified by a static
- expression with value zero (0) and is not defined to be zero (0),
- excepting declarations within a subprogram, generic subprogram, generic
- formal part, task unit, or protected unit.
+ Static Semantics
+
+ A pure library_item is a preelaborable library_item whose elaboration
+ does not perform any of the following actions:
+
+ * the elaboration of a variable declaration;
+ * the evaluation of an allocator of an access-to-variable type;
+ for the purposes of this rule, the partial view of a type
+ is presumed to have non-visible components whose default
+ initialization evaluates such an allocator;
+
+ QUESTION: Can we instead require that a type with preelaborable
+ initialization not evaluate an allocator of an access-
+ to-variable type as part of its default initialization?
+ In Ada 95, types with preelaborable initialization were
+ allowed to have access discriminants with a default
+ being an allocator.
+
+ * the elaboration of the declaration of a named
+ access-to-variable type for which the Storage_Size
+ has not been specified by a static expression with value zero
+ and is not defined by the language to be zero;
+
+ * the elaboration of the declaration of a named
+ access-to-constant type for which the Storage_Size
+ has been specified by an expression other than a static
+ expression with value zero.
+
+ AARM NOTE: We allow access-to-constant types so long as there
+ is no user-specified non-zero Storage_Size; if there were a
+ user-specified non-zero Storage_Size restricting the size of
+ the storage pool, allocators would be problematic since the
+ package is supposedly "stateless", and the allocated size count for
+ the storage pool would represent state.
+ The Storage_Size for an anonymous access-to-variable type declared at
+ library level in an unit that is declared pure is defined to be zero.
+
+ Legality Rules
+
+
+
Replace 10.2.1(17)
A pragma Pure is used to declare that a library unit is pure. If a
pragma Pure applies to a library unit, then its compilation units
@@ -136,7 +187,7 @@
the earlier call. This permission applies even if the subprogram
produces other side effects when called.
-Add after 13.13.2(1/1):
+Add after 13.13.2(36/1):
A type is said to support external streaming if Read and Write attributes
are available that provide for sending values of such a type between active
@@ -310,20 +361,58 @@
of the record type declaration. The identifiers of all components of a record
type shall be distinct.
+!corrigendum 4.8(5)
+
+@drepl
+If the type of the @fa<allocator> is an access-to-constant type, the
+@fa<allocator> shall be an initialized allocator. If the designated type is
+limited, the @fa<allocator> shall be an uninitialized allocator.
+@dby
+An @fa<allocator> shall not be of an access type for which the
+Storage_Size has been specified by a static expression with value
+zero or is defined by the language to be zero. 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. This rule does not apply in the body of a generic unit or within
+a body declared within the declarative region of a generic unit, if the
+type of the allocator is a descendant of a formal access type declared
+within the formal part of the generic unit.
+
!corrigendum 10.2.1(16)
@drepl
+@i<@s8<Legality Rules>>
+
A @i<pure> @fa<library_item> is a preelaborable @fa<library_item> that does not
contain the declaration of any variable or named access type, except within a
subprogram, generic subprogram, task unit, or protected unit.
@dby
-A @i<pure> @fa<library_item> is a preelaborable @fa<library_item> that does not
-contain the declaration of any variable, or named access-to-object
-type for which the Storage_Size has not been specified by a static
-expression with value zero (0) and is not defined to be zero (0),
-excepting declarations within a subprogram, generic subprogram, generic
-formal part, task unit, or protected unit.
+@i<@s8<Static Semantics>>
+
+A @i<pure> @fa<library_item> is a preelaborable @fa<library_item> whose
+elaboration does not perform any of the following actions:
+
+@xbullet<the elaboration of a variable declaration;>
+@xbullet<the evaluation of an @fa<allocator> of an access-to-variable type;
+for the purposes of this rule, the partial view of a type
+is presumed to have non-visible components whose default
+initialization evaluates such an @fa<allocator>;>
+
+@xbullet<the elaboration of the declaration of a named
+access-to-variable type for which the Storage_Size
+has not been specified by a static expression with value zero
+and is not defined by the language to be zero;>
+
+@xbullet<the elaboration of the declaration of a named access-to-constant type
+for which the Storage_Size has been specified by an expression other than a
+static expression with value zero.>
+
+The Storage_Size for an anonymous access-to-variable type declared at
+library level in an unit that is declared pure is defined to be zero.
+
+@i<@s8<Legality Rules>>
+
!corrigendum 10.2.1(17)
@drepl
@@ -363,11 +452,19 @@
call. This permission applies even if the subprogram produces other side
effects when called.
-!corrigendum 13.13.2(1/1)
+!corrigendum 13.13.2(36/1)
@dinsa
-The operational attributes Write, Read, Output, and Input convert
-values to a stream of elements and reconstruct values from a stream.
+The stream-oriented attributes may be specified for any type via an
+@fa<attribute_definition_clause>. All nonlimited types have default
+implementations for these operations. An @fa<attribute_reference> for one of
+these attributes is illegal if the type is limited, unless the attribute
+has been specified by an @fa<attribute_definition_clause> or (for a type
+extension) the attribute has been specified for an ancestor type. For an
+@fa<attribute_definition_clause> specifying one of these attributes, the
+subtype of the Item parameter shall be the base subtype if scalar, and the
+first subtype otherwise. The same rule applies to the result of the Input
+function.
@dinss
A type is said to @i<support external streaming> if Read and Write attributes
are available that provide for sending values of such a type between active
@@ -2309,6 +2406,236 @@
is required to note that "only if" means that a limited type with an access
type part must satisify both parts of the rule. It's certainly not obvious on
casual reading.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, July 20, 2005 8:26 PM
+
+In York, we decided to add rules to ban most forms of allocators from Pure
+units, as they represent a form of state. That includes a general rule
+making allocators of an access type with Storage_Size 0 illegal.
+
+Tucker was nice enough (or is that crazy enough) to develop wording for
+this. One of the rules he proposes has a question after it:
+
+Replace 10.2.1(16) by:
+
+ A pure library_item is a preelaborable library_item whose elaboration
+ does not perform any of the following actions:
+
+ ...
+
+ * the evaluation of an allocator of an access-to-variable type;
+ for the purposes of this rule, the partial view of a type
+ is presumed to have non-visible components whose default
+ initialization evaluates such an allocator;
+
+ QUESTION: Can we instead require that a type with preelaborable
+ initialization not evaluate an allocator of an access-
+ to-variable type as part of its default initialization?
+ In Ada 95, types with preelaborable initialization were
+ allowed to have access discriminants with a default
+ being an allocator.
+
+ ...
+
+It may not be really clear from this wording, but this is a fairly serious
+rule, as it prevents the use of most partial views to declare objects in
+pure packages. We had a similar problem with preelaborated packages, which
+was solved with pragma Preelaborable_Initialization (whew!). In York, we had
+no stomach for defining a pragma Pure_Initialization (there are quite a few
+rules needed). So, Tucker just banned everything that might be a problem.
+
+Tucker's question is suggesting that we might instead make this a
+requirement of a type with preelaborable initialization. In that case, the
+rule doesn't disallow as many harmless cases, but it spreads the
+incompatibility to preelaborable units as well.
+
+I don't quite understand Tucker's statement: "In Ada 95, types with
+preelaborable initialization were allowed to have access discriminants with
+a default being an allocator.", because I don't see anything in Ada 95 that
+disallows using an allocator as the default initialization of any component.
+An allocator is not a name (syntactically), so 10.2.1(8) doesn't apply.
+Whether a subprogram call is involved (for the default pool) could be argued
+forever, and in any case, there is no difference between anonymous and named
+types for the evaluation of allocators.
+
+So it seems to me that either allocators were allowed everywhere, or
+nowhere, in default expressions for types used to declare objects in
+preelaborable units. For the moment, I'll assume that allocators are allowed
+(otherwise, the whole question is moot, and we should just ban them
+explicitly and be done with it).
+
+Anyway, that's a side issue. The important question is whether we want to
+ban allocators of access-to-variable types in types with preelaborable
+initialization. This would appear to be somewhat incompatible, but also very
+consistent with the intent of preelaboration to avoid runtime actions. (I
+can't imagine that the default pool for an access-to-variable type could be
+evaluated at compile-time.)
+
+Here's an example:
+
+ package Pre is
+ pragma Preelaborate (Pre);
+
+ type Acc is access all Integer;
+
+ type Rec is record
+ Comp : Acc := new Integer'(1);
+ end record;
+
+ Obj : Rec;
+
+ type Priv is private;
+ pragma Preelaboration_Initialization(Priv);
+ private
+ type Priv is new Rec;
+ end Pre;
+
+Obj would be illegal by the proposed rule, because Rec would not have
+preelaborable initialization, as Comp's default initialization involves an
+allocator for an access-to-variable type. Similarly, (and more important),
+Priv's full declaration would be illegal because it doesn't have
+preelaborable initialization.
+
+Note that the above is presumed to be legal in Ada 95 (other than the
+pragma, which won't be recognized).
+
+So, is this an incompatibility or not? If it is, can we stand this
+incompatibility? Should we stand this incompatibility?
+
+Humm. I have to wonder if we need this rule at all. I don't see how such an
+allocator could be evaluated, given the other rules (old and new).
+
+The primary concern that we're trying to prevent is something like:
+
+ package Pure1 is
+ pragma Pure(Pure1);
+
+ type Something (D : access Integer) is record
+ Comp : Boolean;
+ end record;
+
+ subtype Funny is Something (D => new Integer'(0));
+ end Pure1;
+
+Funny is clearly at library level, which means that the accessibility of D
+is library level. So the rule that says that library-level anonymous access
+types in a pure unit have storage size 0 would seem to apply, making the
+allocator illegal.
+
+I can't think of any other way to get an allocator at the library level of a
+pure unit. (You could declare the subtype inside of a component declaration,
+but the semantics would be the same.)
+
+So I'm not sure why we need the rule above. Even if there is something wrong
+with my analysis, we'd be better off just banning library-level subtypes
+like the above in pure units, rather than trying to craft a rule which
+breaks other things:
+
+ * the elaboration of a subtype_indication which evaluates an
+allocator;
+
+Any partial view in a Pure package necessarily has its full view elaborated;
+the above rule would catch problems. Any partial view used in a pure package
+would necessarily come from a pure package. And since no object declarations
+for composite types are allowed in a Pure unit [variables aren't allowed,
+and constants need an initializer which necessarily would not be allowed -
+composite types aren't static], I don't think that you can cause default
+initialization of a partial view anyway. (I've tried for the last half-hour
+to come up with an example...)
+
+If I'm right here, then there is no reason to mess with preelaborable
+initialization (unless we want to), because you can't do anything "pure"
+with a pure partial view anyway. And thus we don't need to worry about what
+goes on inside of them.
+
+OK, everyone, tell me I'm wrong. :-) And what we should do here.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, July 20, 2005 8:56 PM
+
+I should have more carefully read the meeting notes before posting the
+above. The problem case comes from <> in aggregates. As such, it doesn't
+provide a compatibility problem, because it is new. It also can happen in
+extension aggregates, but Ada 95 did not allow the use of a private type as
+the ancestor of an extension aggregate in a preelaborated unit (of which a
+pure unit is a subset). So the private case causes no compatibility
+problems.
+
+The case in question would look something like:
+
+ package Pure1 is
+ pragma Pure(Pure1);
+
+ type Something (D : access Integer) is record
+ Comp : Boolean;
+ end record;
+
+ type Priv is tagged private;
+ pragma Preelaborable_Initialization (Priv);
+ private
+ type Priv is tagged record
+ A_Comp : Something (D => new Integer'(0));
+ end Priv;
+ end Pure1;
+
+ with Pure1;
+ package Pure2 is
+ pragma Pure(Pure2);
+ type New_Type is new Pure1.Priv with null record;
+ C : constant New_Type := (Pure1.Priv with null record);
+ end Pure2;
+
+We need the declaration of C to be illegal because of the allocator in Priv.
+The rule Tucker suggested made all such uses of private types illegal in
+pure units. While we could do better, the lack of a compatibility issue (and
+the existence of one if it is extended to preelaborable units) seems to
+suggest that it is best to use Tucker's rule and move on. (We could allow
+more in the future if it proves desirable.)
+
+Comments?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, July 20, 2005 11:14 PM
+
+It does seem better to keep the rule relatively
+simple; and as you say, we could be more liberal
+in the future.
+
+So when you say "Tucker's rule" you mean the
+one which bans (from pure units) library-level
+constant declarations that make use
+of default initialization of a private type, even if
+that private type has preelaborable initialization.
+
+Although that rule is not really "simple" it
+is simpler than trying to impose additional
+requirements on types with preelaborable initialization.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, July 21, 2005 11:22 AM
+
+> So when you say "Tucker's rule" you mean the
+> one which bans (from pure units) library-level
+> constant declarations that make use
+> of default initialization of a private type, even if
+> that private type has preelaborable initialization.
+
+Yes that's what I meant (the rule I quoted in my first, erroneous message).
+
+> Although that rule is not really "simple" it
+> is simpler than trying to impose additional
+> requirements on types with preelaborable initialization.
+
+Yes, and more compatible.
****************************************************************
Questions? Ask the ACAA Technical Agent