Version 1.2 of 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; --
null;
--
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