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

Differences between 1.10 and version 1.11
Log of other versions for file ai05s/ai05-0005-1.txt

--- ai05s/ai05-0005-1.txt	2007/05/05 01:39:14	1.10
+++ ai05s/ai05-0005-1.txt	2007/07/26 02:58:04	1.11
@@ -267,7 +267,861 @@
 
 ****************************************************************
 
-Editor's note (April 10, 2007): All of the items above this
+From: Adam Beneschan
+Sent: Friday, June 8, 2007  7:25 PM
+
+!topic Minor error in AARM 6.5
+!reference AARM 6.5(5.f/2)
+!from Adam Beneschan 07-06-08
+!discussion
+
+AARM 6.5(5.f) says about an extended_return_statement: "If the return
+statement is left without resulting in a return (for example, due to
+an exception propagated from the _expression_ or the
+_handled_sequence_of_statements_, or a goto out of the
+_handled_sequence_of_statements_), the return object is finalized
+prior to leaving the return statement.
+
+Is "expression" correct in this note?  It would seem to me that if an
+exception is propagated from the evaluation of the expression, the
+return object is not initialized (according to the order that things
+are performed in 6.5(5.8)) and therefore does not need to be finalized
+(see 7.6.1(4)).
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Friday, June 8, 2007  7:37 PM
+
+Looks like you're right about that.  The return object can hardly be finalized
+if it hasn't even been created!  (Fortunately that's only in the AARM.:)
+
+****************************************************************
+
+!topic Bogus AARM information
+!reference AARM 7.6(21.b/2), AARM 7.6.1(24.c/2)
+!from Adam Beneschan 07-06-20
+!discussion
+
+There are a couple places in the AARM that I believe provide incorrect
+information when dealing with a "built-in-place" function call.  I saw
+these when I was trying to figure out what would happen with an
+extended return, and the information threw me off; it took some time
+before I figured out that the AARM was probably incorrect.
+
+Consider:
+
+    with Ada.Finalization;
+    package Pak1 is
+        type String_Acc is access String;
+        type Typ1 is new Ada.Finalization.Controlled with record
+            F1 : Integer;
+            F2 : Integer;
+            F3 : String_Acc;
+        end record;
+--      procedure Initialize (Obj : in out Typ1);
+        procedure Adjust     (Obj : in out Typ1);
+--      procedure Finalize   (Obj : in out Typ1);
+        function Func1 (Val : Integer) return Typ1;
+    end Pak1;
+
+    with Text_IO;
+    package body Pak1 is
+
+        procedure Adjust (Obj : in out Typ1) is
+        begin
+            if Obj.F3 /= null then
+                Obj.F3 := new String' (Obj.F3.all);
+            end if;
+        end Adjust;
+
+        function Func1 (Val : Integer) return Typ1 is
+        begin
+            return Ret : Typ1 do
+                Ret.F1 := Val * 2;
+                Ret.F2 := Val * 3;
+                Ret.F3 := new String' (1 .. Val => '?');
+            end return;
+        end Func1;
+
+    end Pak1;    
+
+    with Pak1;
+    procedure Test1 is
+        Z : Pak1.Typ1 := Pak1.Func1 (1000);
+    begin
+        Pak2.Do_Something_With (Z);
+    end Test1;
+
+When Z is initialized, 7.6(21) gives the implementation permission to
+have Func1 build its result directly in Z, without requiring an
+anonymous object; but this isn't a requirement.  If the call to Func1
+creates an anonymous object, then Adjust will be called on Z after
+this anonymous object is copied to Z, and then Finalize will be called
+on the anonymous object (presumably there would be a real Finalize
+that deallocates F3).  If the implementation takes advantage of the
+permission, then it would seem the extended return statement would
+essentially be setting up Z.F1, Z.F2, and Z.F3.  No Adjust would be
+necessary on Z, and an Adjust would not be desirable since it would
+result in two copies of the same string, one of which would not be
+part of any object of type Typ1 and thus would never be deallocated by
+Finalize.  So it would seem that Adjust is not called at all by the
+declaration of Z.  Am I right, that this is how things are "supposed"
+to work?
+
+In fact, this seems to be confirmed by AARM 7.6(2.b/2): "When an
+object is created, if it is explicitly assigned an initial value, the
+object is either built-in-place from an aggregate or function call (in
+which case neither Adjust nor Initialize is applied), or the
+assignment copies and adjusts the initial value."
+
+But 7.6(21.b/2) seems to directly contradict this.  After mentioning
+the aggregate case in 21.a, 21.b says, "Similarly, in the function
+call case, the anonymous object can be eliminated. Note, however, that
+Adjust must be called directly on the target object as the last step
+of the assignment, since some of the subcomponents may be
+self-referential or otherwise position-dependent. This Adjust can be
+eliminated only by using one of the following permissions."  
+
+(The "following permissions" refer to cases where a variable isn't
+actually used except by dead code, so they wouldn't apply in the above
+example.)
+
+This seems wrong.
+
+If I'm correct, then 7.6.1(24.c/2) is wrong also:
+
+"Either Initialize or Adjust, but not both, is applied to (almost)
+every controlled object when it is created: Initialize is done when no
+initial value is assigned to the object, whereas Adjust is done as
+part of assigning the initial value. The one exception is the
+anonymous object initialized created by an aggregate (both the
+anonymous object created for an aggregate, or an object initialized by
+an aggregate that is built-in-place); Initialize is not applied to the
+aggregate as a whole, nor is the value of the aggregate or object
+adjusted."
+
+since there are now two exceptions instead of one.
+
+I realize that this is probably low priority since it's "just" the
+AARM.  But I do refer to the AARM, and I think it's important that the
+AARM not give bad information.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, June 20, 2007   2:53 PM
+
+> There are a couple places in the AARM that I believe provide incorrect
+> information when dealing with a "built-in-place" function call.  I saw
+> these when I was trying to figure out what would happen with an
+> extended return, and the information threw me off; it took some time
+> before I figured out that the AARM was probably incorrect.
+
+I don't think the AARM is incorrect, although it might not be clear as it
+could be. (That's true for the normative wording as well.)
+
+>Consider:
+>
+>    with Ada.Finalization;
+>    package Pak1 is
+>        type String_Acc is access String;
+>        type Typ1 is new Ada.Finalization.Controlled with record
+>            F1 : Integer;
+>            F2 : Integer;
+>            F3 : String_Acc;
+>        end record;
+>--      procedure Initialize (Obj : in out Typ1);
+>        procedure Adjust     (Obj : in out Typ1);
+>--      procedure Finalize   (Obj : in out Typ1);
+>        function Func1 (Val : Integer) return Typ1;
+>    end Pak1;
+>
+>    with Text_IO;
+>    package body Pak1 is
+>
+>        procedure Adjust (Obj : in out Typ1) is
+>        begin
+>            if Obj.F3 /= null then
+>                Obj.F3 := new String' (Obj.F3.all);
+>            end if;
+>        end Adjust;
+>
+>        function Func1 (Val : Integer) return Typ1 is
+>        begin
+>            return Ret : Typ1 do
+>                Ret.F1 := Val * 2;
+>                Ret.F2 := Val * 3;
+>                Ret.F3 := new String' (1 .. Val => '?');
+>            end return;
+>        end Func1;
+>
+>    end Pak1;
+>
+>    with Pak1;
+>    procedure Test1 is
+>        Z : Pak1.Typ1 := Pak1.Func1 (1000);
+>    begin
+>        Pak2.Do_Something_With (Z);
+>    end Test1;
+
+> When Z is initialized, 7.6(21) gives the implementation permission to
+> have Func1 build its result directly in Z, without requiring an
+> anonymous object; but this isn't a requirement.  If the call to Func1
+> creates an anonymous object, then Adjust will be called on Z after
+> this anonymous object is copied to Z, and then Finalize will be called
+> on the anonymous object (presumably there would be a real Finalize
+> that deallocates F3).  If the implementation takes advantage of the
+> permission, then it would seem the extended return statement would
+> essentially be setting up Z.F1, Z.F2, and Z.F3.  No Adjust would be
+> necessary on Z, and an Adjust would not be desirable since it would
+> result in two copies of the same string, one of which would not be
+> part of any object of type Typ1 and thus would never be deallocated by
+> Finalize.  So it would seem that Adjust is not called at all by the
+> declaration of Z.  Am I right, that this is how things are "supposed"
+> to work?
+
+But you forgot to include a call to Initialize in your description. I see
+that you have Initialize commented out, but a null Initialize is still
+called. It's a mistake to ignore those null calls just because they have no
+effect, it is hard enough to figure out what is supposed to happen without
+leaving out part of the equation.
+
+The declaration of Ret : Typ1 in your example calls Initialize. (If that had
+been initialized with an aggregate, there would have been no call to
+Initialize, different story.) 6.5(5.8/2) says that the object is initialized
+by default, and that wording is a defined term which includes all of the
+stuff, including calling Initialize.
+
+The only thing that is a real rule is that only "pairs" of finalization
+operations are removed, so if a Finalize is removed, an Adjust is removed
+somewhere, too. (We didn't write it that way because there may be more than
+two operations in a "pair" if control flow intercedes, but at run time it is
+always a pair.)
+
+I do agree that Adjust isn't called by the declaration of Z, because
+Initialize is instead (and you never call them both on the same object for
+the same operation).
+
+> In fact, this seems to be confirmed by AARM 7.6(2.b/2): "When an
+> object is created, if it is explicitly assigned an initial value, the
+> object is either built-in-place from an aggregate or function call (in
+> which case neither Adjust nor Initialize is applied), or the
+> assignment copies and adjusts the initial value."
+>
+> But 7.6(21.b/2) seems to directly contradict this.  After mentioning
+> the aggregate case in 21.a, 21.b says, "Similarly, in the function
+> call case, the anonymous object can be eliminated. Note, however, that
+> Adjust must be called directly on the target object as the last step
+> of the assignment, since some of the subcomponents may be
+> self-referential or otherwise position-dependent. This Adjust can be
+> eliminated only by using one of the following permissions."
+
+7.6(21.b/2) is just a continuation of the Ada 95 note 7.6(21.a), and it says
+*exactly* the same thing (with more words). Clearly, if either are wrong,
+both are.
+
+In any case, it is clear that these are talking about assignments into
+existing objects (including those that were previously Initialized), and not
+build-in-place into new objects. (The later has completely different [null]
+semantics and can never be combined with any discussion of "real"
+assignment.) That's true in virtually every note in the AARM that talks
+about dynamic semantics of assignment; you don't "assign" into a new object,
+only into existing ones.
+
+Now, maybe there is some wording that could be added that would help clarify
+this, but it would have to be added in literally dozens of places, and in
+such a way that it would not make the information harder to understand (the
+point of AARM notes is to clarify, after all).
+
+> (The "following permissions" refer to cases where a variable isn't
+> actually used except by dead code, so they wouldn't apply in the above
+> example.)
+>
+> This seems wrong.
+>
+> If I'm correct, then 7.6.1(24.c/2) is wrong also:
+>
+> "Either Initialize or Adjust, but not both, is applied to (almost)
+> every controlled object when it is created: Initialize is done when no
+> initial value is assigned to the object, whereas Adjust is done as
+> part of assigning the initial value. The one exception is the
+> anonymous object initialized created by an aggregate (both the
+> anonymous object created for an aggregate, or an object initialized by
+> an aggregate that is built-in-place); Initialize is not applied to the
+> aggregate as a whole, nor is the value of the aggregate or object
+> adjusted."
+>
+> since there are now two exceptions instead of one.
+
+No, this is correct as written. There may be intermediate function calls,
+but they're irrelevant. Ultimately, you either get initialized directly by
+an aggregate, or Initialize is called. In your example, Initialize is
+called. So I don't see any other exceptions.
+
+> I realize that this is probably low priority since it's "just" the
+> AARM.  But I do refer to the AARM, and I think it's important that the
+> AARM not give bad information.
+
+It's low priority because not much (if anything) is wrong. It looks like
+you're just confused about where Initialize is called. The only reason I see
+for making a change is that you were confused, and that always suggests that
+things aren't as clear as they should be somewhere.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, June 20, 2007   2:52 PM
+
+I believe what is misleading about 7.6(21.b/2) is
+that it only applies to assignment_statement, while
+it uses the term "assignment."  The wording it replaced
+properly used the term "assignment_statement," and
+I think that term should continue to be used in the revised
+wording.
+
+I don't see what is wrong with 7.6.1(24.c/2), since I believe
+the only case where Adjust is not called is when, at
+least "deep down," there is an aggregate.  It might
+be returned through several function calls that use
+build-in-place for return, but underneath it all
+there needs to be an aggregate.  It could probably be
+a bit clearer, I suppose, about the possibility of
+intervening function returns.
+
+****************************************************************
+
+From: Adam Beneschan
+Sent: Wednesday, June 20, 2007   4:18 PM
+
+> > When Z is initialized, 7.6(21) gives the implementation permission to
+> > have Func1 build its result directly in Z, without requiring an
+> > anonymous object; but this isn't a requirement.  If the call to Func1
+> > creates an anonymous object, then Adjust will be called on Z after
+> > this anonymous object is copied to Z, and then Finalize will be called
+> > on the anonymous object (presumably there would be a real Finalize
+> > that deallocates F3).  If the implementation takes advantage of the
+> > permission, then it would seem the extended return statement would
+> > essentially be setting up Z.F1, Z.F2, and Z.F3.  No Adjust would be
+> > necessary on Z, and an Adjust would not be desirable since it would
+> > result in two copies of the same string, one of which would not be
+> > part of any object of type Typ1 and thus would never be deallocated by
+> > Finalize.  So it would seem that Adjust is not called at all by the
+> > declaration of Z.  Am I right, that this is how things are "supposed"
+> > to work?
+> 
+> But you forgot to include a call to Initialize in your
+> description....
+
+Right, I could have been more precise about that.  I really didn't see
+that it made a difference, though, since the AARM paragraph I was
+questioning made no reference to Initializing.  OK, now I see how this
+affects the *second* one I was complaining about (7.6(24.c/2)).
+
+ 
+> 7.6(21.b/2) is just a continuation of the Ada 95 note 7.6(21.a), and it says
+> *exactly* the same thing (with more words). Clearly, if either are wrong,
+> both are.
+
+Interesting---I didn't see it that way at all when I read it.  The way
+the paragraph breaks are organized, it made it look like the part of
+7.6(21.b/2) after the first sentence applied only to this paragraph,
+not to the previous one.
+
+ 
+> In any case, it is clear that these are talking about assignments into
+> existing objects (including those that were previously Initialized), and not
+> build-in-place into new objects. 
+
+Why is this clear?  The notes 7.6(21.a-21.b) follow, and seem to apply
+to, 7.6(21), which talks *both* about build-in-place for new objects
+*and* assignment statements; I don't see anything in the text that
+would indicate that 21.a-21.b apply to the assignment-statement part
+of 21 but not to the build-in-place-for-new-objects part.  I think
+Tuck already addressed this... the previous version of 21.b referred
+to an "assignment_statement", which would have made things clearer in
+the rest of the paragraph, but that reference got deleted.
+
+
+> (The later has completely different [null]
+> semantics and can never be combined with any discussion of "real"
+> assignment.) That's true in virtually every note in the AARM that talks
+> about dynamic semantics of assignment; you don't "assign" into a new object,
+> only into existing ones.
+
+Well, I was going to respond that 3.3.1(19) used the term "assigned"
+to put an initial value into a new object.  But now I notice that this
+language got moved up to the preceding paragraph which only applies to
+objects with no initialization expression.  So I guess that change
+made your statement correct.  :)
+
+There's still 7.6(13):
+
+"When a target object with any controlled parts is assigned a value,
+either when created or in a subsequent assignment_statement, the
+assignment operation proceeds as follows:"
+
+which does make it seem that you *do* assign into a new object.  But I
+guess you could say this is only the case if the Implementation
+Permission (or Implementation Requirement, for limited types) not to
+create a temporary anonymous object is followed, in which case 7.6(15)
+of course does not apply either.  It appears to me that the whole
+build-in-place concept seems to make some statements in the Dynamic
+Semantics sections false, which suggests to me that it should have
+been defined and dealt with in Dynamic Semantics rather than in
+Implementation Requirements/Permissions, but it's probably too late to
+change that now.
+
+
+> > If I'm correct, then 7.6.1(24.c/2) is wrong also:
+> >
+> > "Either Initialize or Adjust, but not both, is applied to (almost)
+> > every controlled object when it is created: Initialize is done when no
+> > initial value is assigned to the object, whereas Adjust is done as
+> > part of assigning the initial value. The one exception is the
+> > anonymous object initialized created by an aggregate (both the
+> > anonymous object created for an aggregate, or an object initialized by
+> > an aggregate that is built-in-place); Initialize is not applied to the
+> > aggregate as a whole, nor is the value of the aggregate or object
+> > adjusted."
+> >
+> > since there are now two exceptions instead of one.
+> 
+> No, this is correct as written. There may be intermediate function calls,
+> but they're irrelevant. Ultimately, you either get initialized directly by
+> an aggregate, or Initialize is called. In your example, Initialize is
+> called. So I don't see any other exceptions.
+
+Yeah, I'll concede this... I forgot about the Initialize on Ret.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, June 20, 2007   5:48 PM
+
+> I believe what is misleading about 7.6(21.b/2) is
+> that it only applies to assignment_statement, while
+> it uses the term "assignment."  The wording it replaced
+> properly used the term "assignment_statement," and
+> I think that term should continue to be used in the revised
+> wording.
+
+But that would be wrong, because it equally applies to initial assignments
+where an anonymous object was used (as Adam pointed out in his analysis).
+Also, whatever applies here also applies to 7.6(21.a), which talks about a
+"value adjustment".
+
+One way to fix this would be to rewrite both paragraphs to make clear that
+they do not apply to "build-in-place assignment to a newly created object",
+but it's not clear to me that that would help the understandability of it.
+Realistically, build-in-place is not really assignment at all (no bits are
+copied), and considering it that is really confusing. I suppose we don't
+have any hope of fixing that directly, but maybe we could at least do
+something to make sense for the notes. Maybe we need to define "genuine
+assignment" for use in the AARM to describe cases where bits are actually
+copied. (I'd prefer "real assignment" for that, but that could be confused.)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, June 20, 2007   6:04 PM
+
+...
+> > 7.6(21.b/2) is just a continuation of the Ada 95 note
+> 7.6(21.a), and it says
+> > *exactly* the same thing (with more words). Clearly, if either
+> are wrong,
+> > both are.
+>
+> Interesting---I didn't see it that way at all when I read it.  The way
+> the paragraph breaks are organized, it made it look like the part of
+> 7.6(21.b/2) after the first sentence applied only to this paragraph,
+> not to the previous one.
+
+They were originally separate paragraphs, but there really is no interesting
+difference between then and they should not really be separate. You have to
+do an adjust anytime that you copy bits.
+
+> > In any case, it is clear that these are talking about assignments into
+> > existing objects (including those that were previously Initialized), and
+not
+> > build-in-place into new objects.
+>
+> Why is this clear?
+
+Because it's clear to me, and I wrote these notes. ;-) As I wrote in
+response to Tucker, build-in-place is a different animal altogether, and
+describing it as an assignment is very confusing to the casual reader. Or
+even the casual (or rushed) writer.
+
+> The notes 7.6(21.a-21.b) follow, and seem to apply
+> to, 7.6(21), which talks *both* about build-in-place for new objects
+> *and* assignment statements; I don't see anything in the text that
+> would indicate that 21.a-21.b apply to the assignment-statement part
+> of 21 but not to the build-in-place-for-new-objects part.  I think
+> Tuck already addressed this... the previous version of 21.b referred
+> to an "assignment_statement", which would have made things clearer in
+> the rest of the paragraph, but that reference got deleted.
+
+I as I mentioned to Tuck, that would be wrong. OK, it would be fight but it
+would make the nore far more narrow than it should be. Both notes apply
+anytime bits are copied (but not build-in-place).
+
+I suppose trying to fix these notes rather than deleting them and starting
+over got me into trouble. It happens a lot in the AARM.
+
+In any case, the note had better be true whenever there is a copying of
+bits, because packages like Claw depend totally on that. Not just in
+assignment_statement, but anywhere that bits are copied. You don't need an
+Adjust for build-in-place, because no bits are being copied and presumably
+the object was properly created (most likely with an Initialize) in the
+first place.
+
+> > (The later has completely different [null]
+> > semantics and can never be combined with any discussion of "real"
+> > assignment.) That's true in virtually every note in the AARM that talks
+> > about dynamic semantics of assignment; you don't "assign" into a new
+object,
+> > only into existing ones.
+...
+> There's still 7.6(13):
+>
+> "When a target object with any controlled parts is assigned a value,
+> either when created or in a subsequent assignment_statement, the
+> assignment operation proceeds as follows:"
+>
+> which does make it seem that you *do* assign into a new object.
+
+You misunderstood me. I said *in notes* of the AARM, I was *not* talking
+about the formal definition of the language. Yes, of course build-in-place
+is technically assignment.
+*Informal* uses generally *exclude* build-in-place because no bits are
+copied, no finalization operations happen, etc. -- it's generally not
+interesting. Would you (if you were not language lawyering) consider
+build-in-place to be an assignment? If so, I think you're pretty unusual.
+
+It's highly unfortunate that the useful term "assignment" has been corrupted
+by the language into something meaningless, but I guess that can't be
+helped. But I doubt that there are many AARM notes that I wrote or that the
+Ada 9x team wrote that consider (or except) the vastly different rules for
+build-in-place. So it would not surprise me if you found many more examples
+where notes don't take that into account.
+
+If you find them, I'll put them on the list to be fixed. But I still not
+sure of an appropriate fix that doesn't greatly confuse the issue.
+
+****************************************************************
+
+From: Adam Beneschan
+Sent: Wednesday, June 20, 2007   6:17 PM
+
+> You misunderstood me. I said *in notes* of the AARM, I was *not* talking
+> about the formal definition of the language. Yes, of course build-in-place
+> is technically assignment.
+> *Informal* uses generally *exclude* build-in-place because no bits are
+> copied, no finalization operations happen, etc. -- it's generally not
+> interesting. Would you (if you were not language lawyering) consider
+> build-in-place to be an assignment? If so, I think you're pretty unusual.
+
+Well, you're probably right.  But not *that* unusual. :) No, I
+wouldn't consider that to be assignment---but I do tend to look
+through language-lawyer eyes when trying to figure out what the
+standard requires, which is approximately the same problem I had when
+trying to figure out when an extended return is "completed".
+
+ 
+> It's highly unfortunate that the useful term "assignment" has been corrupted
+> by the language into something meaningless, but I guess that can't be
+> helped. But I doubt that there are many AARM notes that I wrote or that the
+> Ada 9x team wrote that consider (or except) the vastly different rules for
+> build-in-place. So it would not surprise me if you found many more examples
+> where notes don't take that into account.
+> 
+> If you find them, I'll put them on the list to be fixed. But I still not
+> sure of an appropriate fix that doesn't greatly confuse the issue.
+
+Perhaps the best fix would be:
+
+"An implementation is permitted to omit the separate anonymous object
+for an aggregate or function call, and to omit Initialize, Adjust, and
+Finalize calls, when it can do so and still make things work right."
+Not very precise, but at least it wouldn't be confusing.  :)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, June 20, 2007   6:45 PM
+
+I take it you are suggesting that there be no notes at all? (Useless notes
+like this one add nothing to the language-defined permission, after all.)
+That surely would be one solution to the confusion.
+
+BTW, your suggested wording is very close to something someone else proposed
+a couple of months ago (for a different but related issue). I think it
+captures the essence nicely, but of course it is completely meaningless
+(what does "work right" mean?).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, June 20, 2007   11:45 PM
+
+>> I believe what is misleading about 7.6(21.b/2) is
+>> that it only applies to assignment_statement, while
+>> it uses the term "assignment."  The wording it replaced
+>> properly used the term "assignment_statement," and
+>> I think that term should continue to be used in the revised
+>> wording.
+> 
+> But that would be wrong, because it equally applies to initial assignments
+> where an anonymous object was used (as Adam pointed out in his analysis).
+> Also, whatever applies here also applies to 7.6(21.a), which talks about a
+> "value adjustment".
+
+I still don't agree.  The last sentence of 7.6(21.b/2)
+is referring to an assignment statement based on
+my reading.  7.6(21/2) talks about two things.  One
+is build-in-place when the RHS is an aggregate or
+function call.  The other is about an assignment
+statement where the RHS is non-overlapping, or
+the assignment is done component-at-a-time (carefully).
+I believe the last sentence of 7.6(21.b/2) is referring
+to this last part of 7.6(21/2), which is specifically
+talking about assignment statements.  The whole point
+of the last sentence of 7.6(21.b/2) is that you cannot
+eliminate the Adjust, even if you eliminate the anonymous
+intermediate object.  On the other hand, it is no
+problem to eliminate the Adjust when doing build-in-place
+where the RHS is an aggregate, and in fact it would
+be wrong to do an Adjust for any build-in-place
+assignment from an aggregate.
+
+For what it is worth, I find the *first* sentence of 7.6(21.b/2)
+to be curious, as it seems to be repeating the content of
+the first sentence of 7.6(21/2), and I think may be an
+unintentional remnant, and should be deleted.  Otherwise,
+someone needs to explain what "function call" it is
+referring to, if not to the one already mentioned in
+the first part of 7.6(21/2).
+> 
+> One way to fix this would be to rewrite both paragraphs to make clear that
+> they do not apply to "build-in-place assignment to a newly created object",
+> but it's not clear to me that that would help the understandability of it.
+
+You seem to be implying that build-in-place on a preexisting object
+in an assignment statement requires an Adjust.  I don't understand
+that.  I think build-in-place eliminates the need for Adjust,
+both when creating a new object and when assigning to a
+preexisting object.  If there is no separate object that is going to
+be finalized after the adjust, then we don't want to do the
+adjust.
+
+One challenge is that I don't believe it is really feasible
+to do build-in-place for an assignment *statement* when the RHS is
+a function call, since you clearly need to evaluate the
+RHS before finalizing the LHS, but you must finalize the LHS
+before changing it.  So build-in-place for an assignment *statement*
+really only works if you can evaluate all of the subcomponents
+of the aggregate *without* storing them in the target object,
+then finalize the target object, and then (with aborts deferred)
+assign each of the subcomponents into the LHS.  I believe
+you need to defer aborts since you don't want a Finalize
+to be applied to the LHS when is in the middle of being
+overwritten.  But in any case, you don't want to call Adjust
+if you build-in-place.  Adjust really only makes sense if you
+are copying the bits of a fully-formed object into another
+location.  I believe that is what 7.6(17.1/2) is saying.  Even though
+the requirement to build-in-place only exists for assignments
+which are *not* part of an assignment statement, I believe the
+*meaning* of build-in-place and the requirement to *omit* the
+Adjust is provided by 7.6(17.1/2), and then applies to the
+use of the term in 7.6(21/2).
+
+It would be weird if you would have to use
+slightly different aggregates depending on
+whether you were assigning to a newly created object versus
+a pre-existing object.  In both cases you want the aggregates
+to represent fully adjusted values.  For example, if an
+adjust increments a reference count for a pointed-to object,
+and finalize decrements the reference count, the aggregate
+would want to initialize the reference count of the
+pointed-to object to "1".  E.g.
+
+    (x, y, new indir_obj'(ref_count => 1, ...), z)
+
+would be the appropriate way to write an aggregate for
+such a type, no matter in what context it is used.
+
+I am coming around to thinking that the AARM notes following
+7.6(21/2) are pretty badly broken.  I would recommend
+we make them simpler and clearer, perhaps as follows:
+
+Replace 7.6(21.a & b) with:
+
+   Ramification:  Note that in the second case, where the anonymous
+   object is eliminated but the new value is not created directly
+   in the target object, Adjust must be called directly on the target
+   object as the last step of the assignment, since some of the
+   subcomponents may be self-referential or otherwise position-
+   dependent. This Adjust can be eliminated only by using one
+   of the following permissions.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, June 21, 2007   12:38 AM
+
+> I still don't agree.  The last sentence of 7.6(21.b/2)
+> is referring to an assignment statement based on
+> my reading.  7.6(21/2) talks about two things.  One
+> is build-in-place when the RHS is an aggregate or
+> function call.  The other is about an assignment
+> statement where the RHS is non-overlapping, or
+> the assignment is done component-at-a-time (carefully).
+> I believe the last sentence of 7.6(21.b/2) is referring
+> to this last part of 7.6(21/2), which is specifically
+> talking about assignment statements.  The whole point
+> of the last sentence of 7.6(21.b/2) is that you cannot
+> eliminate the Adjust, even if you eliminate the anonymous
+> intermediate object.  On the other hand, it is no
+> problem to eliminate the Adjust when doing build-in-place
+> where the RHS is an aggregate, and in fact it would
+> be wrong to do an Adjust for any build-in-place
+> assignment from an aggregate.
+
+Why do you never, even comment on 7.6(21.a)? What possible value adjustment
+is there in a build-in-place initialization by an aggregate???
+
+Anyway, I can't believe that you are telling me, the author of the sentence
+in question what it means. I *know* what it means; maybe what I intended
+isn't right, but I deleted the "assignment_statement" from 7.6(21.b/2) on
+purpose because this (I think) covers more than just assignment statements.
+It applies any time bits of the entire cbject are copied as part of an
+assignment operation, no matter what permissions are applied -- as long as
+there still is an overall bit copy of the whole object (not just individual
+components).
+
+Now I see you are trying to tie it solely to 7.6(21/2), but I often try to
+make generally useful statements: there is always an Adjust.
+
+...
+> For what it is worth, I find the *first* sentence of 7.6(21.b/2)
+> to be curious, as it seems to be repeating the content of
+> the first sentence of 7.6(21/2), and I think may be an
+> unintentional remnant, and should be deleted.  Otherwise,
+> someone needs to explain what "function call" it is
+> referring to, if not to the one already mentioned in
+> the first part of 7.6(21/2).
+
+I put it there to set the stage for the rest of it. If it just followed a
+paragraph about aggregates, the reader would reasonably think that we were
+only talking about aggregates in 7.6(21.b/2). Feel free to suggest something
+better.
+
+> > One way to fix this would be to rewrite both paragraphs to make clear that
+> > they do not apply to "build-in-place assignment to a newly created object",
+> > but it's not clear to me that that would help the understandability of it.
+>
+> You seem to be implying that build-in-place on a preexisting object
+> in an assignment statement requires an Adjust.
+
+I don't think that there can be any such thing, at least if there is a
+non-trivial Adjust. Otherwise, the model of 0 or 1 Initialize followed by
+(Finalize/Adjust) followed by Finalize no longer works (you have objects
+that are potentially Initialized multiple times).
+
+> I don't understand
+> that.  I think build-in-place eliminates the need for Adjust,
+> both when creating a new object and when assigning to a
+> preexisting object.  If there is no separate object that is going to
+> be finalized after the adjust, then we don't want to do the adjust.
+
+I don't see how you can "build-in-place" self-referencing pointers properly.
+(Especially now that we know return objects aren't aliased; you can't even
+write such a thing.) If you can prove that they don't exist, you can remove
+the Adjust, but only then.
+
+> One challenge is that I don't believe it is really feasible
+> to do build-in-place for an assignment *statement* when the RHS is
+> a function call, since you clearly need to evaluate the
+> RHS before finalizing the LHS, but you must finalize the LHS
+> before changing it.  So build-in-place for an assignment *statement*
+> really only works if you can evaluate all of the subcomponents
+> of the aggregate *without* storing them in the target object,
+> then finalize the target object, and then (with aborts deferred)
+> assign each of the subcomponents into the LHS.  I believe
+> you need to defer aborts since you don't want a Finalize
+> to be applied to the LHS when is in the middle of being
+> overwritten.
+
+Exactly; it's impractical, if not impossible (I think it is impossible).
+
+> But in any case, you don't want to call Adjust
+> if you build-in-place.  Adjust really only makes sense if you
+> are copying the bits of a fully-formed object into another
+> location.  I believe that is what 7.6(17.1/2) is saying.  Even though
+> the requirement to build-in-place only exists for assignments
+> which are *not* part of an assignment statement, I believe the
+> *meaning* of build-in-place and the requirement to *omit* the
+> Adjust is provided by 7.6(17.1/2), and then applies to the
+> use of the term in 7.6(21/2).
+
+But 7.6(17.1/2 explicitly excludes assignment_statement; surely it doesn't
+apply to them.
+
+> It would be weird if you would have to use
+> slightly different aggregates depending on
+> whether you were assigning to a newly created object versus
+> a pre-existing object.
+
+You do, because you have to do *assignment* differently for each. I can't
+imagine how build-in-place would suddenly change that dynamic. One obvious
+requirement is to allocate the memory for sub-components (which only happens
+with a new object).
+
+What the user writes may be the same, but what the compiler generates is
+quite different for the two cases. Build-in-place is impractical in general
+for non-limited types (of course it can be used on types with no controlled
+or discriminant-dependent components).
+
+...
+> I am coming around to thinking that the AARM notes following
+> 7.6(21/2) are pretty badly broken.
+
+Apparently because the model I have of Finalization isn't the same as yours.
+We're going to need to reconcile that...
+
+At least you decided to mention 7.6(21.a) finally.
+
+> I would recommend
+> we make them simpler and clearer, perhaps as follows:
+>
+> Replace 7.6(21.a & b) with:
+>
+>    Ramification:  Note that in the second case,
+
+What second case? That's way too vague (I don't see any obvious "second
+case" in 7.6(21/2)).
+
+>    ... where the anonymous
+>    object is eliminated but the new value is not created directly
+>    in the target object, Adjust must be called directly on the target
+>    object as the last step of the assignment, since some of the
+>    subcomponents may be self-referential or otherwise position-
+>    dependent. This Adjust can be eliminated only by using one
+>    of the following permissions.
+
+That's OK and I suppose we can agree on this in the sense that it is very
+limited in scope. (And it mainly is intended to tell implementers not to
+make the optimization that the early Intermetrics compilers did.)
+
+I do think that you'll find similar problems in other notes in the manual. I
+don't think we think about build-in-place ever when thinking about
+assignment, and it really is not an assignment. But one problem at a time...
+
+****************************************************************
+
+Editor's note (July 25, 2007): All of the items above this
 marker have been included in the working version of the AARM.
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent