Version 1.4 of ai05s/ai05-0066-1.txt

Unformatted version of ai05s/ai05-0066-1.txt version 1.4
Other versions for file ai05s/ai05-0066-1.txt

!standard 3.10.2(14.4/2)          08-02-22 AI05-0066-1/04
!standard 7.6.1(13/2)
!standard 7.6.1(13.1/2)
!class binding interpretation 07-10-22
!status ARG Approved 8-0-1 08-02-10
!status work item 07-10-22
!status received 07-09-13
!priority High
!difficulty Hard
!qualifier Error
!subject Temporary objects are required to live too long
!summary
When an aggregate or function call is used to initialize an object, and an anonymous object is used to temporarily hold the result, we define the master of the anonymous object to be the expression itself, so that it gets finalized. However, we transfer the coextensions, if any, to the object being initialized as part of the assignment, prior to finalizing the anonymous object.
!question
Consider the following three items (assume that F and G are function returning objects with controlled parts, and that no build-in-place permissions are used for these objects):
(1) Obj := F(G(...)); (2) Ren : T renames F(G(...)); (3) Obj : T := F(G(...));
(In the following "anon_F" is the return object for the function call to F.)
The accessibility of the return object of a function call is defined by 3.10.2(10/2) to be that of the innermost master unless it is used to initialize an object in its entirety. This rule makes it possible for anon_F and anon_G to have different lifetimes. Moreover, the AARM notes claim that the "innermost master that evaluated the function call" does not include the function call itself.
Starting with the easiest case: for (1), the assignment_statement is a master (it is the execution of a statement - by 7.6.1(3/2)). Moreover, the special case of initializing an object in its entirety doesn't apply, and the function call F isn't a master (G is never a master), so both anon_F and anon_G are finalized at the end of the assignment statement.
For (2), the function_call (which is a name) is a master (by 7.6.1(3/2)) as it is not nested in any of the things that would prevent from being a master. The special case doesn't apply either (a renames isn't an initialization), but the function_call F is a master. Thus anon_G is finalized as soon as F completes its evaluation and call. OTOH, since we'll believe the AARM note (even though the actual wording doesn't make it clear that the function call is not the innermost master that evaluated the function call), anon_F will have the master that evaluated the renames (and the accessibility of the renamed object will also be that). Thus the object will stick around until the end of the innermost non-package body or block that includes the rename. That's what we want.
For (3), the function_call (which is an expression) is a master (by 7.6.1(3/2)) as it is not nested in any of the things that would prevent from being a master. In this case, the special case (of initialization in its entirety) does apply, so the accessibility of anon_F is that of Obj. The effect is that both the special case and the normal case give the same result: anon_F has the accessibility of Obj. So again, anon_G is finalized as soon as F completes its evaluation and call. But when does anon_F get finalized? The wording would seem to say that it has to wait until the end of the innermost non-package body or block that contains the object declaration, since it has the accessibility of that declaration. That could be a long time in the future, and is different than what Corrigendum 1 requires. When is this object supposed to be finalized?
!recommendation
(See summary.)
!wording
Modify 3.10.2(14.4/2) as follows (this includes the wording change of AI05-0024-1):
In the first case, the allocated object is said to be a coextension of the object whose discriminant designates it, as well as of any object of which the discriminated object is itself a coextension or subcomponent. {If the allocated object is a coextension of an anonymous object representing the result of an aggregate or function call that is used (in its entirety) to directly initialize a part of an object, after the result is assigned, the coextension becomes a coextension of the object being initialized and is no longer considered a coextension of the anonymous object.} All coextensions of an object {(which have not thus been transfered by such an initialization)} are finalized when the object is finalized (see 7.6.1).
Add the following note after 7.6.1(9.1):
AARM NOTE: In the case of an aggregate or function call that is used
(in its entirety) to directly initialize a part of an object, the coextensions of the result of evaluating the aggregate or function call are transfered to become coextensions of the object being initialized and are not finalized until the object being initialized is ultimately finalized, even if an anonymous object is created as part of the operation.
Modify 7.6.1(13) as follows:
The master of an object is the master enclosing its creation whose accessibility level (see 3.10.2) is equal to that of the object{, except in the case of an anonymous object representing the result of an aggregate or function call. The master of such an anonymous object is the innermost master enclosing the evaluation of the aggregate or function call, which may be the aggregate or function call itself}.
AARM NOTE:
In 3.10.2 we assign an accessibility level to the result of an aggregate or function call that is used to directly initialize a part of an object based on the object being initialized. This is important to ensure that any access discriminants denote objects that live at least as long as the object being initialized. However, if the result of the aggregate or function call is not built directly in the target object, but instead is built in an anonymous object that is then assigned to the target, the anonymous object needs to be finalized after the assignment rather than persisting until the target object is finalized (but not its coextensions). (Note than an implementation is never required to create such an anonymous object, and in some cases is required to not have such a separate object, but rather to build the result directly in the target.)
Modify 7.6.1(13.1/2) as follows:
In the case of an expression that is a master, finalization of any (anonymous) objects occurs [as the final part of] {after completing} evaluation of the expression {and use of the objects, prior to starting the execution of any subsequent construct}.
!discussion
The definition of accessibility level for function results and aggregates given in the first sentence of 3.10.2(10/2) is relevant when the object might have an access discriminant, or when the the result might be built directly in the object being initialized. However, unless the type is limited, it is generally implementation-defined whether the result will be built directly in the target. On the other hand, when a separate anonymous object is created for a function or aggregate, we want that object to be finalized after use. We accomplish this by associating a shorter-lived master with any temporary object used to hold the value of the aggregate or function call, while still assigning it an accessibility level that will ensure the appropriate accessibility checks are performed and the appropriate accessibility level for any coextensions.
BACKGROUND
It has been suggested that this AI should be combined with AI05-0067-1. However, this AI deals with cases where the lifetime of the objects is required to be too long in the canonical semantics. The problem is worst for functions that are not build-in-place. Having accessibility (and thus legality) depend on the type of objects is uncomfortable. Moreover, since build-in-place is an implementation option for any function call of any type, tying accessibility to build-in-place would essentially make accessibility implementation-defined, which is really uncomfortable. Thus we conclude that this issue is separate from build-in-place and should be solved independently.
7.6(21/2) gives a permission to eliminate the anonymous object completely. But there is no permission to finalize the object early.
Two possible solutions to this problem have been proposed:
(1)
Changing the rules so that an object declaration is a master (but not of the object).
But this has the potential of causing extra accessibility checks (and failures), because the function object will not have the same accessibility as the object. For instance, consider a function used to initialize an object of a non-limited type with access discriminants:
type Foo (DA : access Integer) is record ... function F (D : access Integer) return Foo;
C : constant Foo := F (new Integer'(10));
We want the accessibility of anon_F and C to the the same; otherwise, the object accessed by the discriminant DA might disappear before the object C does. If F uses parameter D as the discriminant of the return object, it will disappear before the object.
An alternative is to mix build-in-place into this brew, by exempting the parts of an object that are directly constructed in place from this new master (they would have the accessibility of the object). However, besides making accessibility implementation-dependent as noted previously, this does not fix the problem noted above (as build-in-place is not required for type Foo).
(2)
Give an Implementation Permission to allow early finalization of objects with controlled parts if they are not accessible by any path other than the finalization mechanism.
This would allow implementations to finalize the temporories as soon as they are copied.
This has the advantage of also solving the garbage collection problem (Ada does not allow garbage collection of controlled objects, because there is no permission to finalize them early).
But this isn't a requirement, so the incompatibility with the Corrigendum would remain, and temporaries could live a long time. That could be fixed by an Implementation Requirement to finalize function return objects that are copied by object declarations immediately at the end of the object declaration.
Note that allowing finalizations at any time would mean that almost anything could be interrupted by finalizations. That would make programs hard to reason about. In addition, allowing early finalizations of objects containing tasks could unpredictably stall the program waiting for task termination. Thus, tasks that are not waiting for termination need to be excluded from early finalization. An Implementation Permission like the following would be recommended:
An implementation is permitted to finalize an object earlier than these rules would otherwise allow if the object is not accessible by any path at the point of the earlier finalization, and so long as any task parts of the object are either completed or waiting at a terminate alternative. Such a finalization is only allowed during the finalization of a master[, and the object ceases to exist after the finalization].
(The part in square brackets is repeated from 7.6(11/2), and thus follows; we would need to explicitly say something else if we don't want that.)
!corrigendum 3.10.2(14.4/2)
Replace the paragraph:
In the first case, the allocated object is said to be a coextension of the object whose discriminant designates it, as well as of any object of which the discriminated object is itself a coextension or subcomponent. All coextensions of an object are finalized when the object is finalized (see 7.6.1).
by:
In the first case, the allocated object is said to be a coextension of the object whose discriminant designates it, as well as of any object of which the discriminated object is itself a coextension or subcomponent. If the allocated object is a coextension of an anonymous object representing the result of an aggregate or function call that is used (in its entirety) to directly initialize a part of an object, after the result is assigned, the coextension becomes a coextension of the object being initialized and is no longer considered a coextension of the anonymous object. All coextensions of an object (which have not thus been transfered by such an initialization) are finalized when the object is finalized (see 7.6.1).
!corrigendum 7.6.1(13/2)
Replace the paragraph:
The master of an object is the master enclosing its creation whose accessibility level (see 3.10.2) is equal to that of the object.
by:
The master of an object is the master enclosing its creation whose accessibility level (see 3.10.2) is equal to that of the object, except in the case of an anonymous object representing the result of an aggregate or function call. The master of such an anonymous object is the innermost master enclosing the evaluation of the aggregate or function call, which may be the aggregate or function call itself.
!corrigendum 7.6.1(13.1/2)
Replace the paragraph:
In the case of an expression that is a master, finalization of any (anonymous) objects occurs as the final part of evaluation of the expression.
by:
In the case of an expression that is a master, finalization of any (anonymous) objects occurs after completing evaluation of the expression and use of the objects, prior to starting the execution of any subsequent construct.
!ACATS Test
** TBD **
!appendix

From: Randy Brukardt
Sent: Thursday, September 13, 2007  8:19 PM

I've been trying to justify the objective of a submitted ACATS test, and I've kinda gone
into the accessibility rabbit hole. Let me try to explain what I'm wondering about.

The objective in question is:

Check that a function call renamed as an object is not finalized until the unit
or block that directly contains the renaming is left.

I'm pretty certain that this is in fact what we want (whether or not the rules say it),
but I'm having trouble proving to myself that the rules have this effect. And if they
do, then I'm convinced that object declarations are screwed up.

Consider the following three items (assume that F and G are function returning
objects with controlled parts, and that no build-in-place permissions are used for
these objects):

(1)  Ren : T renames F(G(...));
(2)  Obj : T := F(G(...));
(3)  Obj := F(G(...));

For (1), the function_call (which is a name) is a master (by 7.6.1(3/2)) as it is not
nested in any of the things that would prevent from being a master.

For (2), the function_call (which is an expression) is a master (by 7.6.1(3/2)) as
it is not nested in any of the things that would prevent from being a master.

For (3), the assignment_statement is a master (it is the execution of a statement -
again by 7.6.1(3/2)).

The accessibility of the return object of a function call is defined by 3.10.2(10/2)
to be that of the innermost master unless it is used to initialize an object in its
entirety. This rule makes it possible for F and G to have different lifetimes in (1)
and (2). Moreover, the AARM notes claim that the "innermost master that evaluated
the function call" does not include the function call itself.

Assuming these rules, let's see what happens. (In the following "anon_F" is the return
object for the function call to F.)

Starting with the easiest case: for (3), the special case [of initializing an object in
its entirety - ED] doesn't apply, and the function call F isn't a master (G is never a
master), so both anon_F and anon_G are finalized at the end of the assignment statement.

For (1), the special case doesn't apply either (a renames isn't an initialization), but
the function_call F is a master. Thus anon_G is finalized as soon as F completes its
evaluation and call. OTOH, since we'll believe the AARM note (even though the actual
wording doesn't make it clear that the function call is not the innermost master that
evaluated the function call), anon_F will have the master that evaluated the renames
(and the accessibility of the renamed object will also be that). Thus the object will
stick around until the end of the innermost non-package body or block that includes
the rename. That suggests that the objective is correct, and I can issue the test. Yea.

For (2), the special case does apply and the function_call expression F is a master.
The effect is that both the special case and the normal case gives the same result:
anon_F has the accessibility of Obj. So again, anon_G is finalized as soon as F completes
its evaluation and call. But when does anon_F get finalized? The wording would seem to
say that it has to wait until the end of the innermost non-package body or block that
contains the object declaration, since it has the accessibility of that declaration.
That could be a llooonnnggg time in the future!

I recall the this case was put in so that such a function call (or aggregate) couldn't
fail an accessibility check for no sane reason. But a side effect of that in the case
where the (anonymous) object is immediately copied, we seem to have required it to
stay around a long time. (I realize that the permissions of 7.6 could be used to
eliminate the anonymous object, but those permissions don't allow early finalization,
only *no* finalization.)

I'm not sure what the best fix for this problem is. I note that it is related to the
problem being discussed on comp.lang.ada this week: that the language effectively
requires a storage leak if the construction of an allocated object raises an
exception (because the object cannot be finalized until the access type goes away,
which is likely to be an eternity in the life of the program). One possibility to
fix both cases (and also to allow garbage collection of objects containing controlled
parts) is to add an implementation permission allowing early finalization in limited
cases. Perhaps something like:

   An implementation is permitted to call Finalize on an object of a
   controlled type earlier than these rules would otherwise allow if there is no usage
   of the object after the point of the earlier Finalize call.

But we'd probably want to limit the places that these early calls could happen (don't
want it totally asynchronous). And we probably ought to just say "finalize" and not
limit the type. Maybe just allow it when a master is finalized:

   An implementation is permitted to finalize an object earlier
   than these rules would otherwise allow if there is no usage of the object
   after the point of the earlier finalization. Such a finalization is only allowed
   during the finalization of a master[, and the object ceases to exist after the
   finalization].

[The part in brackets is redundant because it repeats part of 7.6.1(11/2). If we decide
we don't want that, we'd have to define something else.]

Humm, but that could cause random waiting for unreferenced tasks, which would not be
good. So perhaps we do really want to limit such a rule to controlled parts of objects.

Anyway, what do you think? It there any easier way to fix this? Or did I miss something
that prevents a problem? Should we have an AI? Should I just have a beer (or, a Gin
and Tonic in honor of John)?

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

From: Tucker Taft
Sent: Thursday, September 13, 2007  9:25 PM

Groan...

You mention "the special case" and by that I presume
you mean "used directly to initialize part of an object."
If so, then I interpret that to mean "build in place."
So the special case does *not* apply to (2) under
that interpretation.

Unfortunately, that doesn't really help.  At one point
we had declarations as masters, and it is when the
elaboration of a declaration is complete that we want
to clean up all the temps involved in the declaration.
Unfortunately, at some point we decided declarations were
*not* masters, and now these temps live too long.

Yuck.  I think we need to go back to having certain
kinds of declarations as masters, since it is only
when the declaration is fully elaborated that you
want to start reclaiming stuff.  Groan and double groan.

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

From: Randy Brukardt
Sent: Thursday, September 13, 2007  9:59 PM

Yes, we once had declarations as masters. But that make the objects and types
being declared having too deep accessibility (and they effectively would be
destroyed as soon as they were declared). We discussed ways to fix that, but
they looked really messy and we went to the current formulation.

> You mention "the special case" and by that I presume
> you mean "used directly to initialize part of an object."
> If so, then I interpret that to mean "build in place."
> So the special case does *not* apply to (2) under
> that interpretation.

I don't agree with that interpretation (although it doesn't matter in this example).
I believe that rule was added to make coextensions work on some cases (that is, to
make the accessibilities match so we don't have to do checks/have checks fail on
initialization that we surely don't want).

In any case, I don't think that changing the masters helps at all. If we make the
return object be more nested than the thing that it is initializing, then there
are a number of accessibility checks that ought to fail. (I.e. coextension access
discriminants would be more nested than the target object.) And if we *don't* do
that, the anonymous object lives too long.

That's why I think the only solution is to give a garbage collection permission,
so that compilers at least can do the right thing (can't force them too, I don't
think). The only alternative would be to make a special case finalization rule
for this specific case, but I think that would be too ugly for words. (Besides,
we need to deal with the garbage collection/broken allocator problems anyway -
killing three birds with one stone seems like it is worth it, even if it is a
very hard stone to get agreement on).

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

From: Tucker Taft
Sent: Friday, September 14, 2007  6:41 AM

I think we need to consider compatibility here as
well.  Temporaries of declarations were finalized
at the end of the declaration in Ada 95 (well, Ada 2000
to be more precise -- see 7.6.1(13/1)).  I have a
sense that the solution is to make object declarations
masters of everything created during their elaboration
that does *not* end up as part of the object or one
of its coextensions (not including objects created
by allocators of a named type).  This might clarify
the "special case" we are debating as well.

As far as the interpretation of "used directly to
initialize," the term "directly" is used in several
places when we are talking about build in place,
and that is why I believe it is meant to be
interpreted that way here as well.

Unfortunately it looks like we need an AI to revisit
all of these rules, and clarify and/or fix as
needed.

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

From: Randy Brukardt
Sent: Friday, September 14, 2007  12:42 PM

> I think we need to consider compatibility here as
> well.  Temporaries of declarations were finalized
> at the end of the declaration in Ada 95 (well, Ada 2000
> to be more precise -- see 7.6.1(13/1)).  I have a
> sense that the solution is to make object declarations
> masters of everything created during their elaboration
> that does *not* end up as part of the object or one
> of its coextensions (not including objects created
> by allocators of a named type).  This might clarify
> the "special case" we are debating as well.

The compatibility issue is a good point, although code that depends on exactly
where things are finalized is a bit dubious. But I'd want to be wary of crafting
a rule specifically for object declarations, because there may be other cases
which also have problems that we just haven't thought of yet. (Steve, where are
you when I need you?? ;-). I think the Corrigendum 1 rule was easier to understand
than anything we have now, too bad it wasn't general enough.

We really do need to think about addressing those garbage collection issues as well.
Maybe the fix is separable, maybe it isn't, but we shouldn't ignore those issues
as well.

> As far as the interpretation of "used directly to
> initialize," the term "directly" is used in several
> places when we are talking about build in place,
> and that is why I believe it is meant to be
> interpreted that way here as well.

My memory of the rule in question is that we used "directly" to eliminate
confusion about components and indirect assignments, and that it had nothing
to do with build-in-place. If I had thought that it meant build-in-place only,
I surely would have included that information in an AARM note (it would be
highly relevant and not very obvious). Of course, that is just my understanding,
and when it comes to accessibility, everything I know is wrong so that may not
mean much.

In any case, we're going to have to re-figure out what is meant by this.
 
> Unfortunately it looks like we need an AI to revisit
> all of these rules, and clarify and/or fix as
> needed.

Yup. Sounds like great fun. Especially when Steve B. weighs in... :-)

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

From: Tucker Taft
Sent: Friday, September 14, 2007  3:16 PM

Perhaps we can turn this around, and say that if the
result object of an expression/function call/aggregate
is *copied* rather than used "directly" (there's that
word again) as part of the elaboration of a declaration,
then it has the declaration as its master, and is finalized
no later than the completion of the elaboration.  We could even
define the notion of a "temporary" object if we wanted
to use a more common and intuitive term here.  The old
7.6.1(13) used "anonymous" but that is no longer very
helpful.

As far as I can see, object declarations are the only
kind of declaration that could involve the copying of
a temporary object of a type that might need finalization
(but where the expression/function-call/aggregate resulting in
the temporary object is not nested in some other
expression/function-call), so in that sense, I think object
declarations are special.

I agree with the notion of permitting implementations to
finalize a "temporary" object as soon as the object
is no longer "accessible" (oh dear, that term is crowding in on
"accessibility").  We could probably get away without defining
"accessible" if we only use it in an implementation
permission.

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

From: Pascal Leroy
Sent: Friday, September 14, 2007  11:16 PM

> You mention "the special case" and by that I presume
> you mean "used directly to initialize part of an object."
> If so, then I interpret that to mean "build in place."
> So the special case does *not* apply to (2) under
> that interpretation.

Nonono, you are making this up.

In draft 13.995 it had: "a function call that is used as a prefix of a
name, as the actual parameter in a call, or as the expression of an
assignment_statement".  Then you complained, in a mail dated Thu 27-Oct-05
20:19 and titled "3.10.2(10/2) missing cases?" that it was missing
short-circuit and membership and ranges and discrete_choices.  Then Randy
proposed to invert the rule and only list the case where the accessibility
level is *not* that of the master of the function_call.  That how he
invented the phrase "directly initialize".

Nice try, but you don't get to rewrite history ;-)

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

From: Pascal Leroy
Sent: Friday, September 14, 2007  11:28 PM

> For (2), the special case does apply and the function_call 
> expression F is a master. The effect is that both the special 
> case and the normal case gives the same result: anon_F has 
> the accessibility of Obj. So again, anon_G is finalized as 
> soon as F completes its evaluation and call. But when does 
> anon_F get finalized? The wording would seem to say that it 
> has to wait until the end of the innermost non-package body 
> or block that contains the object declaration, since it has 
> the accessibility of that declaration. That could be a 
> llooonnnggg time in the future!

But notice that it's exactly what you want if type T is limited (the
build-in-place case).  Because 3.10.2 and 7.6.1 do not, as far as I can
tell, make any special provision for the build-in-place case, it is
logical that they would not give a permission to destroy anon_F early,
because anon_F might just happen to be another name for Obj.

Also remember that an implementation has the freedom to do build-in-place
all the time, and so we don't want the accessibility rules to get in the
way.

Therefore I believe that the change has somehow to be tied to the
build-in-place Implementation Requirement in 7.5(8.1/2).  It should say
that, if the implementation doesn't do build-in-place, then the anonymous
object gets finalized immediately after it has been copied.

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

From: Randy Brukardt
Sent: Saturday, September 15, 2007 12:42 AM

Neat - the third person to look at this has a completely different idea of
how to fix this than the first two. Looks like this one will be real fun!

One problem with this fix is that "build-in-place" is not formally defined,
so wording such a requirement would be tough. And it would be weird to have
a requirement that applies only if you *don't * take advantage of a permission
(which is sometimes required...). Sounds like that could be a real trip down
the rabbit hole.

I still prefer simply treating this as a special case of garbage collection
(perhaps with an implementation requirement to do it immediately in the
object declaration case). But that isn't ideal, either.

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

From: Pascal Leroy
Sent: Saturday, September 15, 2007  12:30 PM

I have for some time been under the impression that we made a mistake when
we defined the "build-in-place" model using an Implementation Requirement.
The problem we have is that whether an implementation builds in place or
not has an impact on the static and dynamic semantics (for instance, no
adjustment takes place) and it is extremely uncomfortable to have an IR
feeding back on the high-level semantics.

I believe that the build-in-place business should have been (or should be;
this can always be changed by an AI) phrased exclusively in terms of
high-level semantics.  Something like:

For an aggregate of a limited type used to initialize an object as allowed
above, the anonymous object for the aggregate is called a *bip* object.
For a 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 return object (see 6.5) for the function_call is called
a *bip* object.

For a bip object that is used to initialize a final object then:

1 - Any name that denotes the bip object also denotes the final object and
vice-versa.
2 - The assignment operation of the bip object to the final object does
not involve any adjustment, finalization, waiting for tasks, etc.
3 - For the purpose of accessibility checks, masters and other shenanigans
the bip object and the final object are indistinguishable (after the
creation of the bip object).

Implementation Permission

An implementation is allowed to make the anonymous object for a nonlimited
aggregate a bip object.  Similarly for function calls.

AARM Note: A bip object is expected to be built-in-place by the
implementation.  This is not a requirement however: the object may be
copied a million times before being assigned to the final object, provided
that its integrity is maintained.  For instance, any self-pointers would
have to be properly relocated, and any task/protected resources owned by
the OS would have to be unaffected.

Comments?

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

From: Randy Brukardt
Sent: Saturday, September 15, 2007  3:07 PM

The name would have to make more sense than "bip". I thought you misspelled
"big" originally. Maybe we should just call it a "Leroy" object (if we can
have Taft types, we can have Leroy objects. ;-).

Anyway, this probably was the right thing to do 3 years ago, but it seems
like an unnecessary change right now. Especially considering the horrible
handwaving in your proposed wording. We can be that loose in Implementation
Permissions and Implementation Requirements, but not in regular semantics.
That I think is one of the main reasons why these are permissions and
requirements in the first place. We'd need a whole lot better wording
(probably with a lot of Notwithstandings in it) in order to do this change.

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

From: Tucker Taft
Sent: Saturday, September 15, 2007  3:08 PM

> Implementation Permission
> 
> An implementation is allowed to make the anonymous object for a nonlimited
> aggregate a bip object.  Similarly for function calls.
> 
> AARM Note: A bip object is expected to be built-in-place by the
> implementation.  This is not a requirement however: the object may be
> copied a million times before being assigned to the final object, provided
> that its integrity is maintained.  For instance, any self-pointers would
> have to be properly relocated, and any task/protected resources owned by
> the OS would have to be unaffected.

This AARM note does not seem very helpful.  It isn't just self-pointers
that would need to be relocated.  All pointers to the object would
need to be relocated.  This sounds a lot like a relocating garbage
collector.  With a relocating garbage collector, we don't
talk about the object being "copied" but rather being "moved."
The last thing we want is a bunch of copies.  Perhaps I am
just being sensitive to the term "copy" which I associate with there
being one more object after the copy than before.  Perhaps
if you just changed the phrase "copied a million times before being
assigned" to something like:

   moved a millions times before reaching its
   final resting place in the specified target

I would be more comfortable.

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

From: Pascal Leroy
Sent: Saturday, September 15, 2007  7:05 PM

> The name would have to make more sense than "bip".

This was intended to be whimsical, both a shorthand for "built-in-place"
and an allusion to these movies where they replace every 4-letter words by
a beep.  Oh well.

> Anyway, this probably was the right thing to do 3 years ago, 
> but it seems like an unnecessary change right now.

Just to make things clear, the wording was a trial balloon.  Of course, it
would have to be much more precise.  However, I don't think it would be an
"unnecessary change" at this point because we have seen quite a few cases
lately where the Implementation Requirement had an impact on high-level
semantics.  I think that describing the effect of build-in-place in
high-level semantic terms would be much preferable to the current
hand-waving in the IR.

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

From: Tucker Taft
Sent: Sunday, February 3, 2008 10:00 PM

Here is an attempt at fixing the accessibility
level rules for aggregates and function calls used
to initialize an object.  It probably will need to
be coordinated with AI05-67. [This is version /02 of the AI - ED]

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


Questions? Ask the ACAA Technical Agent