Version 1.2 of ai05s/ai05-0218-1.txt

Unformatted version of ai05s/ai05-0218-1.txt version 1.2
Other versions for file ai05s/ai05-0218-1.txt

!standard 7.5(8.2/3)          10-10-18 AI05-0218-1/01
!class binding interpretation 10-06-13
!status work item 10-06-13
!status received 10-04-15
!priority Low
!difficulty Hard
!qualifier Omission
!subject Generics and volatility
!summary
A nonvolatile generic formal derived type precludes a volatile actual type.
!question
The language tries to prevent an access value from denoting a volatile object of a nonvolatile type.
The following example seems to violate this rule.
procedure Volatility_Test is type T1 is record Field : aliased Integer; end record; type T2 is new T1; pragma Volatile (T2);
generic type Formal_Derived is new T1; package G is X : Formal_Derived; type Ref is access all Integer; Ptr : Ref; end G; package body G is begin Ptr := X.Field'access; end G; package I is new G (T2); begin I.Ptr.all := I.Ptr.all + 1; -- problematic references to a volatile null; -- I.Ptr := I.X.Field'Access; -- clearly illegal end Volatility_Test;
Should this be fixed?
!recommendation
(See Summary.)
Delete the 2nd occurrence of the phrase "or allow pass by copy" in C.6(12).
In other words, replace
If an atomic type is used as an actual for a generic formal derived type, then the ancestor of the formal type shall be atomic or allow pass by copy.
with
If an atomic type is used as an actual for a generic formal derived type, then the ancestor of the formal type shall be atomic.
!discussion
The !question and !summary sections talk about volatility, but the wording change mentions only atomicity. This makes sense because of the next sentence in C.6(12):
Corresponding rules apply to volatile objects and types.
!ACATS Test
Add a B-Test to check that this type is classified as "immutably limited".
!appendix

From: Steve Baird
Sent: Thursday, April 15, 2010  7:35 PM

> It seems like the case ought to be detected, or at least we ought to
> consider if the problem is severe enough to fix (as the fix will be
> incompatible).

Ok, I'll inflict this one on the group.

The language tries to prevent an access value from denoting a volatile object of
a nonvolatile type.

The following example seems to violate this rule.
Does this warrant fixing?

   procedure Volatility_Test is
     type T1 is record Field : aliased Integer; end record;
     type T2 is new T1;
     pragma Volatile (T2);

     generic
        type Formal_Derived is new T1;
     package G is
        X : Formal_Derived;
        type Ref is access all Integer;
        Ptr : Ref;
     end G;
     package body G is
     begin
        Ptr := X.Field'Access;
     end G;
     package I is new G (T2);
   begin
     I.Ptr.all := I.Ptr.all + 1; -- problematic references to a volatile
     null;
     -- I.Ptr := I.X.Field'Access; -- clearly illegal
   end Volatility_Test;

Note that C.6(12) currently includes the following:
   ...
   If an atomic type is used as an actual for a generic formal derived
   type, then the ancestor of the formal type shall be atomic or allow
   pass by copy. Corresponding rules apply to volatile objects and
   types.

One solution would be to delete the "or allow pass by copy" wording, although
that change would affect the atomic case as well.

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

From: Randy Brukardt
Sent: Thursday, April 15, 2010  8:03 PM

It should be noted that this rule potentially inflicts a large burden on
implementations that do generic sharing, as it essentially requires anything
whose actual type can be volatile (or atomic) to be passed by copy if that is
allowed at all. For types that allow passing by copy but that the compiler would
normally pass by reference (such as larger composite types), this can be very
expensive. (Alternatively, the compiler could revert to non-sharing semantics
when any actual might be volatile or atomic, but of course that would limit the
sharing possibilities fairly significantly.)

There also seems to be an issue if the compiler choose in the example above to
pass the type by reference in any primitive subprograms. Humm...(answering own
question)...actually T1 int eh example above can't have primitive subprograms
(else the pragma is illegal). So scratch this issue.

Anyway, the sharing issue alone would not be worth changing the language for,
but it seems to provide an additional data point that the existing rule is
dubious.

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

From: Robert Dewar
Sent: Thursday, April 15, 2010  8:08 PM

I am not normally very sympathetic to Randy's concerns about generic sharing,
but in this particular case, I think he has a really good point. This definitely
needs fixing in my view.

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

From: Steve Baird
Sent: Monday, July 19, 2010  6:02 PM

One of my homework items from Valencia is to propose wording for this AI. To
recap, we want prevent an access value from denoting a volatile object of a
nonvolatile type as in the following example:

   procedure Volatility_Test is
     type T1 is record Fld : aliased Integer; end record;
     type T2 is new T1;
     pragma Volatile (T2);

     generic
        type Formal_Derived is new T1;
     package G is
        X : Formal_Derived;
        type Ref is access all Integer;
        Ptr : Ref;
     end G;
     package body G is
     begin
        Ptr := X.Fld'Access;
     end G;
     package I is new G (T2);
   begin
     I.Ptr.all := I.Ptr.all + 1; -- problematic references to a volatile

   end Volatility_Test;

So ...

   !wording

   Append to the end of C.6(12):

     Furthermore, if a volatile type is used as an actual for
     a generic formal derived type, then the ancestor of the formal
     type shall be volatile.

Alternatives include:
    1) In the proposed wording, replace "shall be volatile" with
       "shall be volatile or elementary".  It might appear that there is
       no harm in allowing a generic which has a "new Standard.Integer"
       formal derived type to be instantiated with a volatile actual.
       The problem discussed here has to do with the volatility
       of subcomponents (see final sentence of C.6(8)) and an
       elementary type has no subcomponents. Adding two words to
       allow this case might seem reasonable.

       However, there is another problem which has not been discussed
       which this relaxation might open up.

       4.6(24.9/2) states (in the context of a type conversion between
       two array types unrelated by derivation):
         The operand type of a view conversion shall not have a tagged,
         private, or volatile subcomponent.

       Consider a view conversion between two array types declared in
       a generic body; the two types have our "new Standard.Integer"
       formal derived type as subcomponent of their common element
       type. If we allow a volatile actual type, we can get a
       violation of the above rule and it looks like this could lead
       to problems.

    2) Add no new wording and instead delete the existing phrase
       "or allow pass by copy" from C.6(12). This would disallow
       more than we need to as it would affect the rules for Atomic
       types as well as Volatile types. This seems like a
       significant and unnecessary incompatibility.

    3) Add the new sentence as a new paragraph and drop the leading
       "Furthermore, ". It does seem a odd to have the sentence
          "Corresponding rules apply to volatile objects and types."
       appearing other than at the end of its paragraph.

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

From: Randy Brukardt
Sent: Monday, July 19, 2010  6:24 PM

I didn't think about this in detail, but...

>     2) Add no new wording and instead delete the existing phrase
>        "or allow pass by copy" from C.6(12). This would disallow
>        more than we need to as it would affect the rules for Atomic
>        types as well as Volatile types. This seems like a
>        significant and unnecessary incompatibility.

...this doesn't make sense to me since Atomic always implies Volatile
(C.6(8)) So anything that applies to volatile types also applies to atomic
types, and thus any incompatibility (no matter how it is stated) clearly applies
to atomic as well.

There might be good reasons for not doing this, but the given reason isn't it.

(It should be obvious that the problematic case is even more problematic for
atomic objects, in the event that they are allowed by the implementation.)

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

From: Steve Baird
Sent: Monday, July 19, 2010  6:37 PM

> There might be good reasons for not doing this, but the given reason
> isn't it.

Good point; I had the implication backwards.

I think there are no good reasons for not doing this and the proposed wording
change should simply be that 5-word deletion.

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

From: Steve Baird
Sent: Monday, July 19, 2010  6:49 PM

> ...this doesn't make sense to me since Atomic always implies Volatile
> (C.6(8)) So anything that applies to volatile types also applies to
> atomic types, and thus any incompatibility (no matter how it is
> stated) clearly applies to atomic as well.

I agree with you, but it isn't as obvious as you make it sound.

Consider the case of an atomic formal where the actual is volatile, not atomic,
and allows pass by copy. If this case is possible, then we have a scenario where
the proposed 5-word deletion would be unnecessarily restrictive. But how did we
get this actual which meets all the formal-to-actual matching rules but isn't
atomic? We don't have a "pragma Non_Atomic" which can be applied to a derived
type with an atomic parent.

So I think you are right.

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

From: Tucker Taft
Sent: Monday, July 19, 2010  8:29 PM

You should be careful with misinterpretation of your solution (2), because the
phrase "or allow pass by copy" appears *twice* in C.6(12).  I presume you mean
the second occurrence, which is talking about formal derived types.  And I agree
the most straightforward solution is to eliminate this second "allow pass by
copy".

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

From: Steve Baird
Sent: Tuesday, July 20, 2010  2:56 PM

> You should be careful with misinterpretation of your solution (2),
> because the phrase "or allow pass by copy" appears *twice* in C.6(12).

Good point.

I presume you mean the second
> occurrence, which is talking about formal derived types.

Right.

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

Questions? Ask the ACAA Technical Agent