Version 1.4 of ais/ai-00173.txt

Unformatted version of ais/ai-00173.txt version 1.4
Other versions for file ais/ai-00173.txt

!standard 13.03 (16)          01-01-29 AI95-00173/01
!class binding interpretation 96-11-16
!status work item 98-03-17
!status received 96-11-16
!priority Low
!difficulty Hard
!subject Optimizations and the use of 'Address
!summary 98-03-17
Suppose an execution accesses the same storage twice, at least one of the accesses modifies the storage, and at least one of the accesses is based on an address value. Then the behavior of the execution is unspecified unless at least one of the following conditions holds:
o Each of the accesses is the update or examination of a volatile object.
o Each of the accesses is the update or examination of an object that is
aliased, imported, or exported, is of a by-reference type, or has an address specified by an address clause; and both objects are of the same type.
!question 98-03-17
Common optimization techniques, applied to source code that makes undisciplined use of 'Address, can result in object code with surprising behavior. Under what circumstances are optimizations required to preserve the effects resulting from examining or modifying variables through their addresses?
!response 98-03-17
An access to an object is "based on an address value" if either of the following holds:
o The object is part of an object whose address is specified by an address
clause.
o The object is part of an object designated by an access value that was
generated by an instance of System.Address_To_Access conversions.
Suppose an execution accesses the same storage twice, at least one of the accesses modifies the storage, and at least one of the accesses is based on an address value. Then the behavior of the execution is unspecified unless at least one of the following conditions holds:
o Each of the accesses is the update or examination of a volatile object.
o Each of the accesses is the update or examination of an object that is
aliased, imported, or exported, is of a by-reference type, or has an address specified by an address clause; and both objects are of the same type.
!discussion 98-03-17
A naive approach would be to allow only optimizations valid in the presence of arbitrary aliasing. This approach is impractical because the possibility of arbitrary aliasing is so prevalent that many innocuous optimizations would be inhibited. Consider the following example:
package Pkg is type Integer_Pointer is access all Integer; type Float_Pointer is access all Float; F: aliased Float; end Pkg;
with System.Address_To_Access_Conversions; package Access_Integer_Conversions is new System.Address_To_Access_Conversions(Integer);
with Pkg; use Pkg; procedure Proc1(IP: in Integer_Pointer; FP: in Float_Pointer) is begin IP.all := IP.all + 1; FP.all := FP.all + 1.0; end Proc1;
with Pkg, Access_Integer_Conversions, Proc1; use Pkg, Access_Integer_Conversions; procedure Proc2 is Object_Pointer_To_F: Object_Pointer := To_Pointer(F'Address); Integer_Pointer_To_F: Integer_Pointer := Integer_Pointer(Object_Pointer_To_F); Float_Pointer_To_F: Float_Pointer := F'access; begin Proc1(Integer_Pointer_To_F, Float_Pointer_To_F); end Proc2;
Conventional instruction-scheduling techniques could generate code for Proc1 that loads IP.all into a general register, then loads FP.all into a floating-point register, then adds one to each register, then stores each register. However, as Proc2 demonstrates, it is possible for IP.all and FP.all to overlap, in which case this scheduling of instructions produces a result different from the result of executing the two assignment statements in order. Nonetheless, it would be unreasonable to prohibit a scheduling that interleaves instructions from the two assignment statements in Proc1. A separately compiled subprogram like Proc1 is most likely to be part of a program that does no address manipulation, so that IP.all and FP.all cannot possibly overlap. (6.2(12), on aliasing of subprogram parameters, does not apply in this case; it is not the formal parameters, but the objects they designate, that are aliased.) In contrast, given the procedure
with Pkg; use Pkg; procedure Proc3 (IP1, IP2: in Integer_Pointer) is begin IP1.all := IP1.all + 1; IP2.all := IP2.all + 1; end Proc3;
it is prudent to assume that IP1 and IP2 may be equal, and thus inhibit any optimization that depends on IP1.all and IP2.all occupying disjoint storage.
Our goal is to produce a set of rules that is simple enough to be easily understood, makes common usages safe by default, provides the programmer with a means to make uncommon usages safe, and inhibits relatively few optimizations.
We allow an optimizer to assume that addresses are used in a type-safe manner. That is, potential aliasing between variables of different types need not be considered when determining whether an optimization is safe. A programmer knowingly using addresses to view the same storage as belonging to two different types can (and should) make both views volatile or atomic to inhibit reordering. (This requires implementation support for the shared-variable-control pragmas defined in the Systems Programming annex.) For example, a programmer who knows that Integer_Pointer and Float_Pointer values may designate overlapping objects could use the following version of package Pkg:
package Pkg is type Volatile_Integer is new Integer; pragma Volatile(Volatile_Integer); type Volatile_Float is new Float; pragma Volatile(Volatile_Float); type Integer_Pointer is access all Volatile_Integer; type Float_Pointer is access all Volatile_Float; F: aliased Volatile_Float; end Pkg;
C.6(20) states, "The external effect of a program (see 1.1.3) is defined to include each read and update of a volatile or atomic object." Therefore, 1.1.3(15) inhibits optimizations that reorder reads or updates of such objects.
13.3(16) recommends the following level of support for the Address attribute:
X'Address should produce a useful result if X is an object that is aliased or of a by-reference type, or is an entity whose Address has been specified.
AARM 13.3(16.b) asserts, "An implementation need not go to any trouble to make Address work in other cases," and this is nearly true. However, 13.3(19) adds the following condition to the recommended level of support:
If the address of an object is specified, or it is imported
or exported, then the implementation should not perform optimizations based on assumptions of no aliases.
Thus this interpretation restricts optimizations only in cases where the Standard guarantees the existence of a "useful" address, and in the case of imported or exported objects.
13.7.2(5) defines the behavior of address-to-access conversions as follows:
To_Pointer(X'Address) is equal to X'Unchecked_Access for an X that allows Unchecked_Access. To_Pointer(Null_Address) returns null. For other addresses, the behavior is unspecified.
The Standard provides no guarantees about the behavior of a program that invokes To_Pointer with a value that is not the address of an object X of the type denoted by the generic formal type Object. Since the semantics of type-unsafe address-to-access conversions are already unpredictable, there is nothing to be gained for the programmer by insisting that optimizations preserve the semantics of programs containing such conversions.
The Standard does not attach any such unpredictability to the type-unsafe use of address clauses. For example, the Standard would seem to require Proc1 to be compiled in such a way that it can be invoked as follows and still behave as if its two assignment statements were executed in sequence:
with Pkg, Access_Integer_Conversions, Proc1; use Pkg, Access_Integer_Conversions; procedure Proc2 is I: Integer; for I'Address use F'Address; Integer_Pointer_To_F: Integer_Pointer := I'access; Float_Pointer_To_F: Float_Pointer := F'access; begin Proc1(Integer_Pointer_To_F, Float_Pointer_To_F); end Proc2;
For the reasons explained earlier, this requirement overly restricts the optimizations that may be applied when compiling Proc1. Therefore, we do not require optimizations to preserve the semantics of any program containing type-unsafe use of addresses, except as required by volatile objects.
(It is the treatment of type-safety violations arising from address clauses in the same manner as type-safety violations arising from address-to-access conversions that makes this interpretation a binding interpretation. Otherwise, it would be a ramification of the rules in the Standard.)
!appendix

!section 13.3(16)
!subject Optimizations and the use of 'Address
!reference RM95 13.3(16)
!reference RM95 13.7.1(6)
!from Tucker Taft  96-11-06
!reference 1996-5743.a Tucker Taft 1996-11-6>>
!discussion

If one tries to do relatively aggressive optimization, then
undisciplined use of 'Address can cause havoc.  Unfortunately,
the RM does not provide any guidelines for what is "undisciplined"
use of 'Address.  13.3(16) says that 'Address should produce
a "useful" value for certain cases (including all by-reference
types), and *specifying* the 'Address of an object should disable
certain optimizations.  However, there is no guidance to the
user or the implementor as to what should be the effect of referencing
the 'Address attribute on an object.

Particularly nasty cases occur when a local record or array
is passed as an IN parameter to a function, and the function
simply returns (or stores into a global) the 'Address of the
parameter.  Any stores through the address returned by such
a function could have mysterious and unexpected side-effects
on the pointed-to record or array.  Unless an optimizer gives
up all attempts to optimize uses of record or array components,
it must presume that such mysterious side-effects don't happen.

This leads to some set of restrictions on the use of 'Address
and on stores through an address.  Perhaps the RM should include
a proposed set of restrictions, or at least allow implementations
to impose restrictions on the use of values produced by 'Address.

Here is one possible set of restrictions:

 First, some context:
    We are only worried here about objects that are updated
    by code that makes use only of the object's address, rather
    than via an Ada name that denotes the object.

    There are two interesting points: one where the 'Address
    attribute reference appears; and the other where the actual
    update-via-address takes place.

 Here are the proposed restrictions:

    If an object is going to be updated via its address,
    then at the point of the 'Address, the prefix must
    denote a variable view of the object, and at the point
    of the update, the object must still exist.

    If the point of the 'Address and the point of the
    update-via-address are not in the same subprogram, then
    there must be no reference, by a normal Ada name, to the value of
    the object between the point at which the 'Address is
    taken and the point at which the update-via-address occurs.

Violating any of these restrictions can lead to erroneous execution.

The point of these restrictions is so that the optimizer can
effectively treat a variable whose 'Address is taken as volatile
throughout the subprogram where the 'Address explicitly occurs,
and that the eventual update-via-address can be seen as just
a deferred effect of taking the 'Address (by disallowing references
to the value between the 'Address and the update).

Comments?

-Tuck

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

!section 13.3(16)
!subject Optimizations and the use of 'Address
!reference RM95 13.3(16)
!reference RM95 13.7.1(6)
!from Tucker Taft  96-11-06
!reference 1996-5743.a Tucker Taft 1996-11-6
!reference 96-5744.a Norman H. Cohen 96-11-7>>
!discussion

> Here are the proposed restrictions:
>
> If an object is going to be updated via its address,
> then at the point of the 'Address, the prefix must
> denote a variable view of the object, and at the point
> of the update, the object must still exist.
>
> If the point of the 'Address and the point of the
> update-via-address are not in the same subprogram, then
> there must be no reference, by a normal Ada name, to the value of
> the object between the point at which the 'Address is
> taken and the point at which the update-via-address occurs.

I'm not convinced these rules do the trick.  In a case like

   package Global_Data is
      A: Integer;
         -- NOT declared aliased, but its 'Address is
         --   taken by the caller of P.
   end Global_Data;

   with System.Address_To_Access_Conversions;
   package Integer_Pointer_Conversions is
      new System.Address_To_Access_Conversions (Integer);

   with Integer_Pointer_Conversions;
   use Integer_Pointer_Conversions;
   with Global_Data;
   procedure P (Address_Of_A: in System.Address) is
      Pointer_To_A: constant Object_Pointer :=
                       To_Pointer(Address_Of_A);
      B: Integer;
   begin
      [stuff having nothing to do with A or B];
      Pointer_To_A.all := 0;
      B := Global.A;
      ...
   end P;

the programmer appears to have obeyed the rules, but I see nothing to
prevent the compiler from scheduling the assignment to B before the
update-through-address of A, thus surprising the programmer.  (Of course
similar examples can be constructed with the global scalar replaced by a
composite passed as a by-reference parameter.)

-- Norman

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

!section 13.3(16)
!subject Optimizations and the use of 'Address
!reference RM95 13.3(16)
!reference RM95 13.7.1(6)
!reference 1996-5743.a Tucker Taft 1996-11-6
!reference 1996-5744.a Norman Cohen 1996-11-7
!from Tucker Taft  96-11-07
!reference 1996-5746.a Tucker Taft 1996-11-7>>
!discussion

> > Here are the proposed restrictions:
> >
> > If an object is going to be updated via its address,
> > then at the point of the 'Address, the prefix must
> > denote a variable view of the object, and at the point
> > of the update, the object must still exist.
> >
> > If the point of the 'Address and the point of the
> > update-via-address are not in the same subprogram, then
> > there must be no reference, by a normal Ada name, to the value of
> > the object between the point at which the 'Address is
> > taken and the point at which the update-via-address occurs.
>
> I'm not convinced these rules do the trick.  In a case like
>
>    package Global_Data is
>       A: Integer;
>          -- NOT declared aliased, but its 'Address is
>          --   taken by the caller of P.
>    end Global_Data;
>
>    with System.Address_To_Access_Conversions;
>    package Integer_Pointer_Conversions is
>       new System.Address_To_Access_Conversions (Integer);
>
>    with Integer_Pointer_Conversions;
>    use Integer_Pointer_Conversions;
>    with Global_Data;
>    procedure P (Address_Of_A: in System.Address) is
>       Pointer_To_A: constant Object_Pointer :=
>                        To_Pointer(Address_Of_A);
>       B: Integer;
>    begin
>       [stuff having nothing to do with A or B];
>       Pointer_To_A.all := 0;
>       B := Global.A;
>       ...
>    end P;
>
> the programmer appears to have obeyed the rules, but I see nothing to
> prevent the compiler from scheduling the assignment to B before the
> update-through-address of A, thus surprising the programmer.  (Of course
> similar examples can be constructed with the global scalar replaced by a
> composite passed as a by-reference parameter.)

It looks like there is another relevant "point" in the equation, namely
the point where the conversion from 'Address back to an access value
takes place, relative to where the update takes place.
I would presume that if the optimizer "sees" this conversion from
Address to access value it can presume that something is fishy, and
perhaps take appropriate precautions (though tracking where that value
wonders may not be easy).

However, if that conversion appears deep inside some function,
then the optimizer has no clue that the access value through which
it is storing is a "dangerous" one.

One possible additional requirement is that the subprogram where the
update-via-address takes place may not have *any* reference to the
value of the variable via a normal Ada name.  This would solve the
above problem, presumably, but then we get into what happens if
there is inlining of code, or interprocedural "optimization"
(destruction?).

Here is one possible alternative for the second paragraph:

    Any update-via-address must occur before the subprogram
    containing the 'Address returns, and the only references
    to the value of the variable by a normal Ada name before
    the subprogram returns must be within the subprogram itself,
    and not in some subprogram it calls.

But that is perhaps too limiting...

Any other suggestions?

Perhaps the above is sufficient to cover cases where the
object is not marked "aliased" or "Volatile" or "exported."

It basically lets you take 'Address of a parameter for the purpose
of updating it before you return, even if the actual corresponding
to the parameter is not aliased, volatile, or exported.  For globals
whose 'Address is taken, aliased, Volatile, or Export would be required.

> -- Norman

-Tuck

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

!section 13.3(16)
!subject Optimizations and the use of 'Address
!reference RM95 13.3(16)
!reference RM95 13.7.1(6)
!reference 1996-5743.a Tucker Taft 1996-11-6
!reference 1996-5744.a Norman Cohen 1996-11-7
!reference 1996-5746.a Tucker Taft 1996-11-7
!from Norman Cohen  96-11-07
!reference 96-5747.a Norman H. Cohen 96-11-7>>
!discussion

> Any other suggestions?

The straightforward rule would be that it is erroneous to update a variable
by its address and refer to the variable by its Ada name in the same
program, unless the variable is marked volatile (by one of the pragmas
Volatile, Atomic, Volatile_Components, or Atomic_Components).  It does not
suffice for the variable to be marked aliased:  An aggressive optimizer
could note that there are no local updates through access-to-T and deduce
that references to objects of type T can be safely moved.

Formally, this is a glaring upward incompatibility.  In practical terms,
due to the unpredictable nature of erroneous execution, existing compilers
can continue to do what they are now doing and existing code, even if it
becomes formally erroneous, will continue to behave (or misbehave) as it
always did, at least until the code is recompiled by a more aggressively
optimizing compiler.

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

!section 13.3(16)
!subject Optimizations and the use of 'Address
!reference RM95 13.3(16)
!reference RM95 13.7.1(6)
!reference 1996-5743.a Tucker Taft 1996-11-6
!reference 1996-5744.a Norman Cohen 1996-11-7
!reference 1996-5746.a Tucker Taft 1996-11-7
!reference 1996-5747.a Norman Cohen 1996-11-7
!from Tucker Taft 96-11-07
!reference 1996-5749.a Tucker Taft 1996-11-7>>
!discussion

> > Any other suggestions?
>
> The straightforward rule would be that it is erroneous to update a variable
> by its address and refer to the variable by its Ada name in the same
> program, unless the variable is marked volatile (by one of the pragmas
> Volatile, Atomic, Volatile_Components, or Atomic_Components).  It does not
> suffice for the variable to be marked aliased:  An aggressive optimizer
> could note that there are no local updates through access-to-T and deduce
> that references to objects of type T can be safely moved.

Yes, it seems like Volatile or Ex/Import is required for globals
whose 'Address is going to be taken (Ex/Import does the job thanks
to 13.3(19)).

However, for non-globals, this seems too draconian, since there is no way
to apply Volatile or Export/Import to a formal parameter.  I think
something like the restriction I proposed in my second message would work,
namely that if 'Address is taken in a subprogram, and the variable is not
Volatile/Ex/Imported, then the update-via-address must occur before
the subprogram returns, and any value references by Ada name must be
restricted to the subprogram where the 'Address explicitly occurs.

> Formally, this is a glaring upward incompatibility.  In practical terms,
> due to the unpredictable nature of erroneous execution, existing compilers
> can continue to do what they are now doing and existing code, even if it
> becomes formally erroneous, will continue to behave (or misbehave) as it
> always did, at least until the code is recompiled by a more aggressively
> optimizing compiler.

I don't think that is acceptable, given the common use of 'Address on
a formal parameter for doing otherwise relatively portable binary I/O.

-Tuck

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

!section 13.3(16)
!subject Optimizations and the use of 'Address
!reference RM95 13.3(16)
!reference RM95 13.7.1(6)
!reference 1996-5743.a Tucker Taft 1996-11-6
!reference 1996-5744.a Norman Cohen 1996-11-7
!reference 1996-5746.a Tucker Taft 1996-11-7
!reference 1996-5747.a Norman Cohen 1996-11-7
!reference 1996-5749.a Tucker Taft 1996-11-7
!from Norman Cohen 96-11-07
!reference 96-5751.a Norman H. Cohen 96-11-7>>
!discussion

> > Formally, this is a glaring upward incompatibility.  In practical terms,
> > due to the unpredictable nature of erroneous execution, existing compilers
> > can continue to do what they are now doing and existing code, even if it
> > becomes formally erroneous, will continue to behave (or misbehave) as it
> > always did, at least until the code is recompiled by a more aggressively
> > optimizing compiler.
>
> I don't think that is acceptable, given the common use of 'Address on
> a formal parameter for doing otherwise relatively portable binary I/O.

Does this use involve updating an object through its address and then
examining it through its Ada name?

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

!section 13.3(16)
!subject Optimizations and the use of 'Address
!reference RM95 13.3(16)
!reference RM95 13.7.1(6)
!reference 1996-5743.a Tucker Taft 1996-11-6
!from Randy Brukardt 96-11-07
!reference 96-5752.a Randy Brukardt  96-11-7>>
!discussion

>If one tries to do relatively aggressive optimization, then=20
>undisciplined use of 'Address can cause havoc.  Unfortunately,
>the RM does not provide any guidelines for what is "undisciplined"
>use of 'Address.  13.3(16) says that 'Address should produce
>a "useful" value for certain cases (including all by-reference
>types), and *specifying* the 'Address of an object should disable
>certain optimizations.  However, there is no guidance to the
>user or the implementor as to what should be the effect of referencing
>the 'Address attribute on an object.

I agree with your note this far, but then you get much too complicated.

I have always viewed the RM as saying that the only 'Addresses which =
have
to work are those specified in 13.3(16).  Other ones may produce a =
result,
but optimization may make that result useless.  We changed our manual
to stress that to users years ago (that was one of the first Ada 95 =
changes
made to our documentation).

I don't think there is any special optimizations needed for aliased, =
by-reference, or specified types, since they already are handled =
specially by
optimizers.  'Address on them will work as expected.

I see little reason that the language should guarentee more.

Of course, as a practical matter, compilers will support more so as not =
to
make existing Ada 83 code fail to work.  However, that is not a language
issue -- Ada 83 compilers were very inconsistent on this point.  I know =
that
some other compilers (not ours) could not take 'Address of constants or
some local variables when optimization was on.  (We implemented special
code for those cases in order to make them to work).  Thus, any Ada 83
code using 'Address was not portable to other Ada compilers anyway.  I
don't think it would be benefical to Ada to require some compilers to =
support
more 'Address uses.

In my view, 'Address (as a query) should have been an obsolecent feature
anyway.  Just about every use of it would be better handled with =
stronger
typing using 'Access or 'Unchecked_Access.  It wasn't made such because
specification of it is still useful.  I think it is crazy to waste much =
time (or
especially implementation effort) trying to figure out how it ought to =
work in
the face of optimization.

                        Randy.

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

!section 13.3(16)
!subject Optimizations and the use of 'Address
!reference RM95 13.3(16)
!reference RM95 13.7.1(6)
!reference 1996-5743.a Tucker Taft 1996-11-6
!reference 1996-5752.a Randy Brukardt 1996-11-7
!from Tucker Taft 96-11-7
!reference 1996-5753.a Tucker Taft 1996-11-7>>
!discussion

> ...
> I agree with your note this far, but then you get much too complicated.
>
> I have always viewed the RM as saying that the only 'Addresses which =
> have
> to work are those specified in 13.3(16).  Other ones may produce a =
> result,
> but optimization may make that result useless.  We changed our manual
> to stress that to users years ago (that was one of the first Ada 95 =
> changes
> made to our documentation).
>
> I don't think there is any special optimizations needed for aliased, =
> by-reference, or specified types, since they already are handled =
> specially by
> optimizers.  'Address on them will work as expected.
>
> I see little reason that the language should guarantee more.

Even if we limit ourselves to aliased and by-reference, many aggressive
optimizers will be flumoxed if the update-via-address occurs in a random
place.  Are you saying that every local object of a by-reference type
is trashed by any subprogram call?  That seems a bit overly pessimistic.

Similarly, just being aliased seems insufficient, since Ada-oriented
optimizers could normally presume that an aliased object of type
T could only be altered by an assignment through an access-to-T.
There is nothing precluding converting the 'Address of an aliased
object to an access-to-T1, and storing through that.

In any case, it seems we need a stronger statement in the RM
saying that storing through a value produced by 'Address has
implementation-defined effects.  It would be ideal if we could
also provide guidance to implementors and users as to what should normally
be safe to do with 'Address, and what would often be unsafe.

> ...
>                       Randy.

-Tuck

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

!section 13.3(16)
!subject Optimizations and the use of 'Address
!reference RM95 13.3(16)
!reference RM95 13.7.1(6)
!reference 1996-5743.a Tucker Taft 1996-11-6
!reference 1996-5752.a Randy Brukardt 1996-11-7
!reference 1996-5753.a Tucker Taft 1996-11-7
!from Randy Brukardt 1996-11-8
!reference 96-5755.a Randy Brukardt  96-11-8>>
!discussion

>Even if we limit ourselves to aliased and by-reference, many aggressive
>optimizers will be flumoxed if the update-via-address occurs in a random
>place.  Are you saying that every local object of a by-reference type
>is trashed by any subprogram call?  That seems a bit overly pessimistic.

Our optimizer assumes EVERYTHING is trashed by any subprogram call.
(Yes, I'm a pessimist by nature.)  Obviously, that's too conservative.  For
Ada 83, where unrestricted use of 'Address was common, it really could
be necessary.  For Ada 95, I would like to see 'Address discouraged
enough that it would be safe to trust that non-aliased (non-volitile, too, I
suppose) local variables aren't trashed.

For me, to tell more, the compiler has to interprocedural optimizations.  That
is especially true since our compiler system allows drop-in assembler
routines, which of course don't necessarily follow any Ada rules.

I realize that my position is essentially equivalent to "aggressive optimization
= incorrect optimization", a minority position at best.  I have always objected
to changing the users code in ways that they can detect (which puts me
into a small minority) -- but, hey I'm in Ada, so I'm ALREADY in a small
minority.  If I wanted to be in the mainstream, I'd be struggling to learn JAVA
now.  :-)

>Similarly, just being aliased seems insufficient, since Ada-oriented
>optimizers could normally presume that an aliased object of type
>T could only be altered by an assignment through an access-to-T.
>There is nothing precluding converting the 'Address of an aliased
>object to an access-to-T1, and storing through that.

I suppose that an optimizer could presume that, although that is more
information than the vast majority of optimizers have.  It would be nice if Ada
was sufficiently strong to justify the investment to build Ada-95-only
optimizers
and code generators from the ground up -- they'd turn out a whole lot better
than the stuff that is out there.  As it is, I expect that most of the Ada 95
systems will use technology that is very similar to their Ada 83 technology,
which would prevent much use of information specific to Ada 95 (like
that of general access types).

>In any case, it seems we need a stronger statement in the RM
>saying that storing through a value produced by 'Address has
>implementation-defined effects.  It would be ideal if we could
>also provide guidance to implementors and users as to what should normally
>be safe to do with 'Address, and what would often be unsafe.

Right.  My position is that doing anything with 'Address is unsafe (other than
specifying it).  Use 'Access if you want to be safe.

                Randy.

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

>From the minutes of the November 1997 ARG meeting:

There was discussion about the optimization capabilities of C and
FORTRAN compilers in handling address operators.  Arguably compilers
effectively optimize around dereferencing of such address values.  Ada
should allow this as well.

Bob, who wrote the paragraph 13.3(16), said that the user was on her
own if she applied 'Address to an object that was not aliased.  First,
the object might not be addressable at all. Second, optimizations
should be allowed to keep non-aliased objects in registers thereby
making 'Address undefined, or cache their value, rendering the use of
the obtained address rather useless.  It would take much more effort
by the compiler to determine non-aliased objects to which 'Address is
applied in order to avoid optimizations that involve this object. (In
fact, such determination is impossible for global variables and their
components).  The wording is currently loose enough to permit the
continued use of 'Address in legacy Ada83 code, while still not
preventing optimizations.

Tuck is proposing some additional restrictions beyond 13.3(16) to
enable subprograms to apply 'Address to a formal parameter, that may
be a part of legacy code.  It's too late to permit the user specify a
formal parameter with the aliased keyword.  Hmmm ... how about creating
a calling convention where formal parameters are aliased???  Not
really.

The group is leaning towards no action or a confirming paragraph
13.3(16), except Tuck's point that using 'Address provides a
language-defined method for violating the type rules.  Several people
feel that this hole should be highlighted as implementation-defined.
Namely, the user who accesses an object both through 'Address and
through its name is courting trouble and must be disciplined to "poke"
the object through 'Address in a type safe manner.

It was observed that "volatile" assures the actuality of values in
memory and will defeat all optimizations regarding the object.
"Aliased" should have the semantics that the compiler should at least
be allowed to assume type-safeness, i.e., an assignment to a
dereferenced "access to T" can only affect objects of type T, no
matter how the access value was obtained.  For any other conversions
of addresses to access types, the user is guaranteed nothing.

Norm will dig into this AI and complete a write-up that handles the
optimization and type safety concerns from the meeting.

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

From: 	Norman H Cohen[SMTP:ncohen@us.ibm.com]
Sent: 	Thursday, April 30, 1998 12:58 PM

The discussion of AI-173 omits the Venn diagram that Tuck drew, which I think
is the key to the solution.  Here is the same hierarchy, presented as a tree:

Address-taken objects
(includes subtrees below +
 X for which X'Address is written locally)
   |
   +---------aliased objects of type T1
   |         (includes subtrees below+
   |          declared aliased+
   |          designated by general access types)
   |             |
   |             +-----objects of type T1 designated
   |             |        by pool-specific type A11
   |             |
   |             +-----objects of type T1 designated
   |                      by pool-specific type A12
   |
   +---------aliased objects of type T2
             (includes subtrees below+
              declared aliased+
              designated by general access types)
                 |
                 +-----objects of type T2 designated
                 |        by pool-specific type A21
                 |
                 +-----objects of type T2 designated
                           by pool-specific type A22

Suppose each object is placed in the innermost applicable Venn-diagram circle,
or the applicable tree node farthest from the root.  Then assignment to a
variable in a given category should force the compiler to regard all objects
placed in the same category, in enclosing categories, and in enclosed
categories to be regarded as potentially modified.  (In the AI, of course, I
have to word that from the point of view of the programmer rather than the
compiler.)

-- Norman
****************************************************************

Editor's note:

The priority of this AI was changed based on ARG discussion in November 2000.

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

Questions? Ask the ACAA Technical Agent