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

Differences between 1.8 and version 1.9
Log of other versions for file ai05s/ai05-0067-1.txt

--- ai05s/ai05-0067-1.txt	2008/06/16 05:33:09	1.8
+++ ai05s/ai05-0067-1.txt	2008/07/11 03:52:12	1.9
@@ -1,5 +1,6 @@
-!standard 4.3.2(5/2)                                         08-06-13    AI05-0067-1/05
+!standard 4.3.2(5/2)                                         08-07-10    AI05-0067-1/06
 !standard 7.5(8.1/2)
+!standard 7.5(9/2)
 !standard 7.6(0)
 !standard 7.6(16)
 !standard 7.6(17/2)
@@ -12,7 +13,7 @@
 !priority High
 !difficulty Hard
 !qualifier Error
-!subject Build-in-place objects
+!subject Objects that are built in place
 
 !summary
 
@@ -20,21 +21,21 @@
 Rather than trying to view the two objects as "the same", the model is
 that there are two distinct objects: the anonymous object (function or
 aggregate result) and the newly-created object (the one being initialized).
-The anonymous object "morphs into" the newly-created object.
+The anonymous object "mutates into" the newly-created object.
 The intended implementation model is still the same: both objects occupy
-the same storage, so this "morphing" is implemented as a no-op in most cases.
+the same storage, so this "mutating" is implemented as a no-op in most cases.
 
 For an extension aggregate of the form "(F(...) with ...)", the Tag of
 the anonymous function result object is that of the function's result type.
 The Tag of the newly-created aggregate object is that of its type.
 Thus, in the case where the result of F is built in place, the Tag of the
 anonymous object is different from the Tag of the newly-created object it
-morphs into.
+mutates into.
 
 For an extension aggregate of the form "(T with ...)" there is only one Tag
 -- that of the aggregate.
 
-Other properties are preserved by the "morphing" operation -- for example,
+Other properties are preserved by the "mutating" operation -- for example,
 access values that designate the anonymous object are updated to designate
 the newly-created object.
 
@@ -59,11 +60,40 @@
 
 !wording
 
-Remove 7.5(8.1/2) and 7.6(17.1/2), which are "Implementation Requirements".
+3.9.1(8.a):  After first sentence, add "It also makes it easier to implement
+extension aggregates in the case where the type is limited, the object is
+allocated from a user-defined storage pool, and the discriminants are
+inherited from the parent type."
+
+Add after 4.3.2(5/2):
+
+If the ancestor_part is a function call and the type of the ancestor_part is
+limited, then the ancestor_part shall have a constrained nominal subtype
+unless there are no components needed in the record_component_association_list.
 
+AARM Reason: This restriction simplifies implementation, because it ensures
+that either the caller or the callee knows the size to allocate for the
+aggregate. Without this restriction, information from both caller and
+callee would have to be combined to determine the appropriate size.
+
+The (F(...) with null record) case is exempt from this rule, because
+(1) it is not needed in that case, and (2) such extension aggregates
+are created internally for inherited functions returning null-extension
+types -- we can't very well make those illegal.
+[end AARM Reason]
+
+Remove 7.5(8.1/2), which is an "Implementation Requirements".
+
+Add "(see 7.6)" to the end of 7.5(9/2).
+
 Rename section 7.6 from "User-Defined Assignment and Finalization"
 to "Assignment and Finalization".
 
+The first sentence of 7.6(16) should be modified:
+  To adjust the value of a [(nonlimited)] composite object, the values of the components
+  of the object are first adjusted in an arbitrary order, and then, if the object is
+  {nonlimited} controlled, Adjust is called.
+
 Add after 7.6(17), the following (this is under "Dynamic Semantics"):
 
 When a function call or aggregate is used to initialize an object, the
@@ -75,15 +105,16 @@
     - If the full type of any part of the object is immutably limited,
       the anonymous object is built in place.
 
-    - In the case of an aggregate, if the type of the newly-created object is
-      controlled, the anonymous object is built in place.
+    - In the case of an aggregate, if the full type of any part of the
+      newly-created object is controlled, the anonymous object is
+      built in place.
 
     - In other cases, it is unspecified whether the anonymous object is
       built in place.
 
 ["Immutably limited type" is defined in AI05-0052-1.]
 
-AARM To Be Honest: We say assignment to build-in-place objects does not
+AARM To Be Honest: We say assignment to built-in-place objects does not
 involve copying, which matches the intended implementation (see below).
 Of course, the implementation can do any copying it likes, if it can make
 such copying semantically invisible (by patching up access values to point
@@ -93,15 +124,20 @@
 parameter passing), this is independent of the view of a type.
 That is, privacy is ignored for this purpose.
 
+AARM Discussion: For function calls, we only require building in place for
+immutable types. These are the types that would have been return-by-reference
+types in Ada 95.We do this because we want to minimize disruption to Ada 95
+implementations and users. [This note was 7.5(8.e/2) - ED]
+
 Notwithstanding what this International Standard says elsewhere, if an object
 is built in place:
 
     - Upon successful completion of the return statement or aggregate,
-      the anonymous object "morphs into" the newly-created object;
+      the anonymous object "mutates into" the newly-created object;
       that is, the anonymous object ceases to exist, and the newly-created
       object appears in its place.
 
-    - Finalization is not performaned on the anonymous object.
+    - Finalization is not performed on the anonymous object.
 
     - Adjustment is not performed on the newly-created object.
 
@@ -111,7 +147,7 @@
     - All renamings of parts of the anonymous object now denote views of the
       corresponding parts of the newly-created object.
 
-    - Coextensions of the anonymous object morph into coextensions of the
+    - Coextensions of the anonymous object become coextensions of the
       newly-created object.
 
 AARM notes:
@@ -120,7 +156,7 @@
   same address as the newly-created object. Thus, no run-time action is
   required to cause all the access values and renamings to point to the right
   place. They just point to the newly-created object, which is what the return
-  object has magically "morphed into".
+  object has magically "mutated into".
 
   There is no requirement that 'Address of the return object is equal to
   'Address of the newly-created object, but that will be true in this
@@ -145,7 +181,7 @@
   be modified at run time. It seems that this model requires the full power of
   tracing garbage collection.
 
-AARM To Be Honest: This "morphing" does not necessarily happen atomically with
+AARM To Be Honest: This "mutating" does not necessarily happen atomically with
 respect to abort and other tasks. For example, if a function call is used as
 the parent part of an extension aggregate, then the tag of the anonymous
 object (the function result) will be different from the tag of the
@@ -155,6 +191,11 @@
 Likewise, if some other task accesses the tag field during this modification,
 it constitutes improper use of shared variables, and is erroneous.
 
+Remove 7.6(17.1/2), which is an "Implementation Requirements". Put the AARM
+notes 7.6(17.h.1-17.i/2) in the group of AARM notes before "Notwithstanding".
+
+Delete "nonlimited" from 7.6(18).
+
 Modify 7.6(21/2) as follows:
 
       [For an aggregate or function call whose value is
@@ -163,42 +204,6 @@
       aggregate or function call directly in the target object. Similarly,
       for]{For} an assignment_statement, ...
 
-3.9.1(8.a):  After first sentence, add "It also makes it easier to implement
-extension aggregates in the case where the type is limited, the object is
-allocated from a user-defined storage pool, and the discriminants are
-inherited from the parent type."
-
-The first sentence of 7.6(16) should be modified:
-  To adjust the value of a [(nonlimited)] composite object, the values of the components
-  of the object are first adjusted in an arbitrary order, and then, if the object is
-  {nonlimited} controlled, Adjust is called.
-
-Delete "nonlimited" from 7.6(18).
-
-Add after 4.3.2(5/2):
-
-If the ancestor_part is a function call and the type requires build-in-place
-(see 7.6), then the ancestor_part shall have a constrained nominal subtype,
-unless the record_component_association_list is *null record*.
-
-AARM Reason: This restriction simplifies implementation, because it ensures
-that either the caller or the callee knows the size to allocate for the
-aggregate. Without this restriction, information from both caller and
-callee would have to be combined to determine the appropriate size.
-
-The (F(...) with null record) case is exempt from this rule, because
-(1) it is not needed in that case, and (2) such extension aggregates
-are created internally for inherited functions returning null-extension
-types -- we can't very well make those illegal.
-[end AARM Reason]
-
-If the ancestor_part is a function call to a generic formal function,
-and the extension_aggregate occurs in a generic body, then the ancestor_part
-shall have a constrained nominal subtype, unless the
-record_component_association_list is *null record*.
-
-AARM Reason: This is essentially an "assume the worst" version of the previous paragraph.
-
 !discussion
 
 Consider the following example. We have an allocator with a limited heap
@@ -255,7 +260,8 @@
      function Make return T1_Ref is
      begin
         return Result : T1_Ref := new T2'
-          (Nested_Pkg.Make_T1 (D1 => 5) with Comp2 => "ABCDEFG") do
+          (Nested_Pkg.Make_T1 (D1 => 5) with -- Now illegal.
+              Comp2 => "ABCDEFG") do
            null;
         end return;
      end Make;
@@ -284,18 +290,68 @@
 implementation terms, this means the Tag will be overwritten in Make, since the
 two objects' Tags are at the same address.
 
-This is complicated enough that we make cases like this illegal.
+The case in Make is complex enough that we make cases with unconstrained nominal
+subtypes (including this one) illegal.
 
 ---
+
 Paragraphs 7.6(16) and 7.6(18) apply to all types, and surely should not claim to
 apply to nonlimited types only.
 
 In addition, 7.6(16) should say that Adjust is called only for nonlimited controlled types,
 so that the canonical semantics is well-defined (limited controlled types do not have
-Adjust).
+Adjust). Note that any non-limited components of a limited type that is not required
+to be built in place could need to be adjusted, so that needs to be well defined.
+
+
+!corrigendum 4.3.2(5/2)
 
+@dinsa
+If the @fa<ancestor_part> is a @fa<subtype_mark>, it shall denote a specific
+tagged subtype. If the @fa<ancestor_part> is an @fa<expression>, it shall not
+be dynamically tagged. The type of the @fa<extension_aggregate> shall be
+derived from the type of the @fa<ancestor_part>, through one or more record
+extensions (and no private extensions).
+@dinst
+If the @fa<ancestor_part> is a function call and the type of the @fa<ancestor_part> is
+limited, then the @fa<ancestor_part> shall have a constrained nominal subtype
+unless there are no components needed in the @fa<record_component_association_list>.
+
+
+!corrigendum 7.5(8)
+
+@ddel
+@i<@s8<Implementation Requirements>>
+
+For an @fa<aggregate> of a limited type used to initialize an object as allowed
+above, the implementation shall not create a separate anonymous object for the
+@fa<aggregate>. For a @fa<function_call> of a type with a part that is of a
+task, protected, or explicitly limited record type that is used to initialize
+an object as allowed above, the implementation shall not create a separate
+return object (see 6.5) for the @fa<function_call>. The @fa<aggregate> or
+@fa<function_call> shall be constructed directly in the new object.
 
---!corrigendum 7.6.1(17.1/1) - Many corrigendum sections to re-insert.
+!corrigendum 7.5(9)
+
+@drepl
+@xindent<@s9<14  While it is allowed to write initializations of limited objects,
+such initializations never copy a limited object. The source of such an
+assignment operation must be an @fa<aggregate> or @fa<function_call>, and such
+@fa<aggregate>s and @fa<function_call>s must be built directly in the target
+object.>>
+@dby
+@xindent<@s9<14  While it is allowed to write initializations of limited objects,
+such initializations never copy a limited object. The source of such an
+assignment operation must be an @fa<aggregate> or @fa<function_call>, and such
+@fa<aggregate>s and @fa<function_call>s must be built directly in the target
+object (see 7.6).>>
+
+!corrigendum 7.6(0)
+
+@drepl
+User-Defined Assignment and Finalization
+@dby
+Assignment and Finalization
 
 !corrigendum 7.6(16)
 
@@ -312,6 +368,67 @@
 object has no effect, nor does adjusting the value of a composite object with no
 controlled parts.
 
+!corrigendum 7.6(17)
+
+@dinsa
+For an @fa<assignment_statement>, after the @fa<name> and @fa<expression> have
+been evaluated, and any conversion (including constraint checking) has been done,
+an anonymous object is created, and the value is assigned into it; that is,
+the assignment operation is applied. (Assignment includes value adjustment.)
+The target of the @fa<assignment_statement> is then finalized. The value of
+the anonymous object is then assigned into the target of the @fa<assignment_statement>.
+Finally, the anonymous object is finalized. As explained below, the implementation
+may eliminate the intermediate anonymous object, so this description subsumes
+the one given in 5.2, “Assignment Statements”. 
+@dinss
+When a function call or @fa<aggregate> is used to initialize an object, the
+result of the function call or @fa<aggregate> is an anonymous object, which
+is assigned into the newly-created object.
+Under certain circumstances, the anonymous object is @i<built in place>,
+in which case the assignment does not involve any copying. In particular:
+
+@xbullet<If the full type of any part of the object is immutably limited,
+the anonymous object is built in place.>
+
+@xbullet<In the case of an @fa<aggregate>, if the full type of any part of the
+newly-created object is controlled, the anonymous object is built in place.>
+
+@xbullet<In other cases, it is unspecified whether the anonymous object is
+built in place.>
+
+Notwithstanding what this International Standard says elsewhere, if an object
+is built in place:
+
+@xbullet<Upon successful completion of the return statement or aggregate,
+the anonymous object @i<mutates into> the newly-created object;
+that is, the anonymous object ceases to exist, and the newly-created
+object appears in its place.>
+
+@xbullet<Finalization is not performed on the anonymous object.>
+
+@xbullet<Adjustment is not performed on the newly-created object.>
+
+@xbullet<All access values that designate parts of the anonymous object now
+designate the corresponding parts of the newly-created object.>
+
+@xbullet<All renamings of parts of the anonymous object now denote views of the
+corresponding parts of the newly-created object.>
+
+@xbullet<Coextensions of the anonymous object become coextensions of the
+newly-created object.>
+
+!corrigendum 7.6(17.1/2)
+
+@ddel
+@i<@s8<Implementation Requirements>>
+
+For an @fa<aggregate> of a controlled type whose value is assigned,
+other than by an @fa<assignment_statement>, the implementation shall not
+create a separate
+anonymous object for the @fa<aggregate>. The aggregate value shall be
+constructed directly in the target of the assignment operation and Adjust is
+not called on the target object.
+
 !corrigendum 7.6(18)
 
 @drepl
@@ -321,6 +438,32 @@
 An implementation is allowed to relax the above rules (for controlled types) in
 the following ways: 
 
+!corrigendum 7.6(21/2)
+
+@drepl
+@xbullet<For an @fa<aggregate> or function call whose value is assigned into a target object,
+the implementation need not create a separate anonymous object if it can safely
+create the value of the @fa<aggregate> or function call directly in the target
+object. Similarly, for an @fa<assignment_statement>, the implementation need not
+create an anonymous object if the value being assigned is the result of
+evaluating a @fa<name> denoting an object (the source object) whose storage cannot
+overlap with the target. If the source object might overlap with the target
+object, then the implementation can avoid the need for an intermediary
+anonymous object by exercising one of the above permissions and perform the
+assignment one component at a time (for an overlapping array assignment), or
+not at all (for an assignment where the target and the source of the assignment
+are the same object).>
+@dby
+@xbullet<For an @fa<assignment_statement>, the implementation need not
+create an anonymous object if the value being assigned is the result of
+evaluating a @fa<name> denoting an object (the source object) whose storage cannot
+overlap with the target. If the source object might overlap with the target
+object, then the implementation can avoid the need for an intermediary
+anonymous object by exercising one of the above permissions and perform the
+assignment one component at a time (for an overlapping array assignment), or
+not at all (for an assignment where the target and the source of the assignment
+are the same object).>
+
 !ACATS Test
 
 This just clarifies the rules, so that additional tests are not needed. However,
@@ -1562,4 +1705,82 @@
 aggregate," since that is exactly when *null record* is allowed.
 
 ****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, July 10, 2008  9:25 PM
+
+My notes for the minutes on AI05-0067-1 say:
+
+Tucker doesn't like the change to 7.6(16). Randy explains the reasons
+(the canonical semantics apply to limited and nonlimited), Tucker would
+prefer no change at all. But Randy disagrees, and Ed eventually stops the
+discussion as non-productive. The rest of the group doesn't seem to have
+an opinion on the issue, so Randy and Tuck are directed to resolve this
+between themselves.
+
+This morning you said that you had come to agree with me, but since there
+are a number of issues where you disagreed with me (but not as significantly),
+I'm not sure we have the right one. So let me explain my reasoning in a
+message and you can tell me if you still want a reword and what it ought to be.
+
+The proposed wording change is to the first sentence of 7.6(16):
+  To adjust the value of a [(nonlimited)] composite object, the values of the components
+  of the object are first adjusted in an arbitrary order, and then, if the object is
+  {nonlimited} controlled, Adjust is called.
+
+The reason for the change is to ensure that the semantics is defined for all
+objects, regardless of whether they are limited or not. I think you were trying to
+convince me that the limited case cannot happen and should not be adjusted at all,
+but I don’t think that is correct.
+
+Remember that this is "limited", not "immutably limited". So this covers types
+that are not necessarily build-in-place. If they are not built-in-place, then
+the "the object is not adjusted" when it mutates doesn't apply and we have to
+define what happens. That is important because we surely want any non-limited
+controlled components to get adjusted. Thus the parenthetical remark is wrong
+and needs to be dropped.
+
+For example:
+
+     package P is
+         type LP is limited private;
+         function Constructor return LP;
+     private
+         type LP is record
+             Comp : <Some Non-limited controlled type>;
+         end record;
+     end P;
+
+     with P;
+     package Q is
+         Obj : P.LP := P.Constructor; -- (1)
+     end Q;
+
+If the function call at (1) is not built-in-place, then there is a copy going on
+for a supposedly limited type. That copy includes Comp, and the Adjust of the
+type of Comp ought to be called (else we would have model breakage where
+Adjusts and Finalizes wouldn't match up and/or pointers wouldn't get updated
+and would point nowhere [and 7.6(26/2) would be violated]).
+
+Technically, we probably don't need the inserted "nonlimited", as any "limited
+controlled" type would require build-in-place and by the new AI05-0067-1 would
+never be adjusted. But I don't like that we've defined this for limited types
+(as noted above) and yet seem to require calling a non-existent procedure
+for limited controlled. That looks bad. I could see adding an AARM "Honest"
+note to say that because of the Notwithstanding build-in-place rules, it's not
+actually possible for a "limited controlled" type be to Adjusted.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, July 10, 2008  9:47 PM
+
+Yes, this was the issue, and yes "I was wrong"!
+The case of a non-build-in-place limited type with nonlimited controlled components
+is exactly the case that convinced me you were right and I was off base.  Clearly
+when you return one of these beasts and it is not built in place, the controlled
+components need to be adjusted.
+
+****************************************************************
+
 

Questions? Ask the ACAA Technical Agent