CVS difference for ais/ai-00246.txt

Differences between 1.2 and version 1.3
Log of other versions for file ais/ai-00246.txt

--- ais/ai-00246.txt	2000/11/04 01:10:29	1.2
+++ ais/ai-00246.txt	2000/11/11 00:08:19	1.3
@@ -1,4 +1,4 @@
-!standard 4.06  (12)                                00-10-31  AI95-00246/01
+!standard 4.06  (12)                                00-11-07  AI95-00246/02
 !class binding interpretation  00-10-31
 !status work item 00-10-31
 !status received 00-10-31
@@ -8,6 +8,9 @@
 
 !summary
 
+A conversion between two limited arrays that do not have a common ancestor is
+illegal.
+
 A view conversion between two arrays that do not have a common ancestor is
 illegal if their component type is has a private or visibly
 by-reference subcomponent.
@@ -22,7 +25,7 @@
     type A2 is array (1..2) of T;
     for A2'Component_Size use 32;
 
-    procedure P (X : A1) is
+    procedure P (X : in out A1) is
     begin
         ...
     end P;
@@ -49,33 +52,25 @@
 Clearly, there is no practical way to generate code for the view conversion.
 Since the type in question is by-reference, the implementation cannot make a
 copy in order to get the appropriate representation.
-
-Thus, the program needs to be made illegal. This could be accomplished by
-making the representation clauses illegal, or by making the view conversion
-illegal.
-
-Making representation items on by-reference types illegal is not very
-attractive. Such a rule would prevent the use of convention pragmas along with
-other items. Moreover, view conversions of untagged type is rare; but this
-solution would eliminate a potentially useful capability in order to eliminate
-a problem with a rarely used feature.
 
-Thus, we make the view conversion illegal.
+This issue is wider than just than view conversions. Consider:
 
-The rule we've adopted is
+    procedure R (X : in A1) is
+    begin
+        ...
+    end R;
 
-   In a view conversion, if the target type and the operand type do not
-   have a common ancestor, then the component subtype shall not have a private
-   or visibly by-reference subcomponent.
+    R (A1 (Y)); -- A value conversion, passed by-reference.
 
-This rule has the benefit of not breaking privateness of private types, nor
-to define an "assume-the-worst" rule for generics. This holds to the contract
-model; the legality of a conversion does not depend on the full definition of
-a type. It means that effectively we're using an assume-the-worst rule for
-all private types.
+In this case, we have a value conversion. Again, the implementation cannot make
+a copy in order to get the appropriate representation, because the components
+are limited by-reference. From a language design perspective, this occurs for
+all limited types. However, the only limited types which are not by-reference
+are limited private types that are completed with a non-limited type -- these
+have a copy operation and thus do not pose an implementation problem.
 
 It might appear that this sort of problem would occur for other untagged
-composite view conversions. (Such conversions must be between derived types.)
+composite conversions. (Such conversions must be between derived types.)
 However, 13.1(10) prevents these sorts of problems for type-related aspects of
 by-reference derived types. So we don't need a rule to handle them. AARM
 13.1(10.b) explains that this rule exists precisely to prevent this sort of
@@ -85,19 +80,66 @@
 the specification of 'Size and/or 'Alignment values that would cause problems
 accessing reference parameters. Thus, no rule is needed to handle this case.
 
-An alternative rule was considered:
-   In a view conversion, if the target type and the operand type do not
-   have a common ancestor and are a by-reference type, then neither type may
+Therefore, the only problems occur for conversions between unrelated array
+types. For both problems, the program needs to be made illegal. This could be
+accomplished by making the representation clauses illegal, or by making the
+conversion illegal.
+
+Making representation items on (array) by-reference types illegal is not very
+attractive. Such a rule would prevent the use of convention pragmas along with
+other items. Moreover, array conversions between unrelated by-reference types
+is rare (and view conversions of such types even rarer). Thus, making the
+representation items illegal would eliminate a potentially useful capability
+in order to eliminate a problem with a rarely used feature.
+
+Therefore, we make the conversions illegal.
+
+The rules we've adopted are
+
+   In an array conversion, if the target type and the operand type do not
+   have a common ancestor, then neither type shall be limited.
+
+   In an array view conversion, if the target type and the operand type do not
+   have a common ancestor, then the component subtype shall not have a private
+   or visibly by-reference subcomponent.
+
+These rules have the benefit of not breaking privateness of private types, nor
+to define an "assume-the-worst" rule for generics. This holds to the contract
+model; the legality of a conversion does not depend on the full definition of
+a type. It means that effectively we're using an assume-the-worst rule for
+all private types.
+
+In addition, these rules can be checked before freezing. This is important for
+the first rule (value conversions can happen in default expressions, and we do
+not want to have to delay legality checking). It is not important for the
+second rule (untagged view conversions cannot happen before freezing, as long
+as IN OUT parameters are not allowed on functions).
+
+Note that these rules have considerable overlap: both rules are triggered for
+the example in the question. However, both rules cover some cases that the
+other does not: the first covers value conversions of limited types, and the
+second covers view conversions of non-limited by-reference types.
+
+Alternative rules were considered:
+   In an array conversion, if the target type and the operand type do not
+   have a common ancestor and are limited, then neither type may
    have a representation item. In addition to the normal places that legality
    rules apply, this also applies in the private part of a generic unit. This
    rule is checked in an assume-the-worst manner in generic bodies.
 
-This rule was rejected mainly because of concerns over determining whether a
-type is by-reference. In particular, that cannot be determined until the type
-is frozen. However, it is not possible in Ada 95 for an array view conversion
-to occur before the type is frozen. (An untagged view conversion requires an
-in out parameter, but that cannot be used in a function call.)
+   In an array view conversion, if the target type and the operand type do not
+   have a common ancestor and are a by-reference type, then neither type may
+   have a representation item. In addition to the normal places that legality
+   rules apply, this also applies in the private part of a generic unit. This
+   rule is checked in an assume-the-worst manner in generic bodies.
 
+These rules were rejected mainly because they cannot be checked until both the
+target and operand types are frozen. (As we saw previously, conversions can
+happen before freezing in default expressions). In addition, these rules
+require breaking privateness (the representation items may be on the full type).
+Finally, these rules don't insure implementable behavior: there is no
+requirement for an implementation to select the same representation for similar
+type declarations.
 
 !corrigendum  4.6(12)
 
@@ -107,6 +149,8 @@
 or neither have aliased components.>
 @dby
 @xbullet<The component subtypes shall statically match; and>
+@xbullet<If the target type and the operand type do not
+have a common ancestor, then the neither type shall be limited; and>
 @xbullet<In a view conversion, the target type and the operand type shall both
 or neither have aliased components; and>
 @xbullet<In a view conversion, if the target type and the operand type do not
@@ -115,7 +159,8 @@
 
 !ACATS test
 
-Create a B-Test which checks that the new rule is enforced.
+Create a B-Test which checks that the new rules are enforced. Include a check
+inside a generic unit.
 
 !appendix
 
@@ -3087,5 +3132,187 @@
 that the opposition to this change would come from the incompatibility. (Or
 worse still, we would forbid the ACATS from testing the rule for that reason,
 giving us an unenforced rule.)
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Monday, November 06, 2000 6:46 AM
+
+> > The primary reason for this wording is to avoid breaking privateness, and to
+> > avoid problems with freezing. Pascal has noted that the standard already
+> > contains at least one legality rule that breaks privateness for by-reference
+> > types (C.6(12)), so it certainly seems harmless to add another.
+>
+> I certainly don't agree that we want to make the slope slipperier!
+> I would rather try to fix C.6(12).  For example, perhaps if a private
+> type is volatile or atomic, that fact needs to be exposed in the visible part.
+> (I'm not sure whether that is addressing Pascal's concern.  I'm just
+> guessing.)
+
+We certainly don't want to add more cases where we are breaking privateness.
+I agree with Tuck's initial proposal, which is that private types should be
+considered by-reference for purposes of the new rule about view conversions.
+
+I also agree that it would be nice to fix C.6(12), although it's not clear
+how to do that in an upward-compatible manner.  Exposing the
+volatility/atomicity of a type in the visible part would be great, but what
+about existing code that assumes that the compiler opens private parts?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, November 06, 2000 5:53 PM
+
+I was finishing up this AI for the meeting, and I started wondering why
+value conversions aren't a problem. After all, the components in this case
+are limited and can't be copied. So, how can you make a value conversion?
+
+Here's an example of what I mean (based on the original example):
+
+    type T is limited null record; -- by-reference
+    type A1 is array (1..2) of T;
+    for A1'Component_Size use 8;
+    type A2 is array (1..2) of T;
+    for A2'Component_Size use 32;
+
+    procedure P (X : in A1) is
+    begin
+        ...
+    end P;
+
+    Y : A2 := ...;
+    ...
+    P (A1 (Y)); -- A value conversion, passed by-reference.
+
+At first thought, you'd think that the conversion would just have to convert
+the representation from A2 to A1. But to do that, it has to decrease the
+space between the components, which means copying them. But the component
+type is limited: no such copying can be done. (Consider that the type might
+be a task or protected object.)
+
+So, it seems to me that ANY conversion of a (really) limited type where a
+representation change is needed is impossible. (Such a type has to be a
+by-reference type, although not all by-reference types fail to have an
+appropriate assignment operation.) 13.1(10) prevents such types from having
+a different representation when they are derived. But there is no such rule
+preventing different representations for unrelated array types (and there
+cannot be such a rule). So, there is a hole for array conversions.
+
+This widens the net somewhat, because the "view" in the proposed rule has to
+be dropped. I suppose we could make this rule apply only to value
+conversions of limited types and all view conversions, but that complicates
+it further.
+
+I hope I'm wrong about this, because I really think Tuck's rule without the
+"view" is really too incompatible to consider. (The advantage of Tuck's rule
+is that is doesn't consider the actual representation, but of course that
+throws out many programs that have no implementation problem.) But I don't
+see why I'm wrong...
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, November 07, 2000 8:52 AM
+
+Randy Brukardt wrote:
+> ...
+>
+> This widens the net somewhat, because the "view" in the proposed rule has to
+> be dropped. I suppose we could make this rule apply only to value
+> conversions of limited types and all view conversions, but that complicates
+> it further.
+
+Be that as it may, that seems like the right rule.  Value conversions are
+useful for non-limited types specifically to do representation conversion
+(by copying).  For limited types, we should disallow all conversions that might
+require a representation change.  This is not just related to arrays.
+It applies to records as well, since one might be packed, and the other
+unpacked.
+
+> I hope I'm wrong about this, because I really think Tuck's rule without the
+> "view" is really too incompatible to consider. (The advantage of Tuck's rule
+> is that is doesn't consider the actual representation, but of course that
+> throws out many programs that have no implementation problem.) But I don't
+> see why I'm wrong...
+
+You are not wrong.  This seems like a much bigger hole, and it has nothing
+really to do with by-reference or by-copy.  Any conversion for limited types
+that changes representation is bad news, as it requires making a copy.
+I would handle this as a separate AI, and probably it deserves a separate fix.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, November 07, 2000 9:18 AM
+
+Really it is a hole in the language. Change of representation inherently
+requires conversions, and limited types don't like the conversions. So basically
+limited types and change of representation are simply incompatible.
+
+Perhaps the rules on restriction of rep clauses if primitive subprograms
+have been defined should apply "ab initio" for limited types (this is too big
+a change I realize, but would be more consistent).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 07, 2000 12:31 PM
+
+Humm, I don't see why you think it is a separate issue. Any uncopyable
+limited type is in fact a by-reference type, so all of the same issues
+apply. (The only limited types that aren't by reference are limited private
+types completed by a non-limited type. The proposed rule covers them, too.)
+
+In any case, the issues are closely related (conversions that cannot be
+performed if there is a representation change). So I don't see why we would
+want to consider them separately, potentially solving them in different
+ways.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, November 07, 2000 1:44 PM
+
+Good point.  I was thinking that all limited types are uncopiable, but
+there is nothing that promises that.  Only by-reference limited types
+are uncopiable, and because of 13.1(10) and the usual weasel-words about
+subtype-specific attributes, this puts us back into only needing to
+worry about unrelated array types.
+
+Now I agree in general, but I would still want to limit the restriction
+to view conversions of possibly by-reference, and value conversions of
+limited possibly-by-reference.  Since the only way to become limited is
+to either be by-reference or limited private, this comes down to
+saying that *all* conversions between unrelated limited array types
+should be disallowed.  I personally don't have a problem with that.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 07, 2000 3:49 PM
+
+OK, I rewrote the AI to make the rules:
+
+   In an array conversion, if the target type and the operand type do not
+   have a common ancestor, then neither type shall be limited.
+
+   In an array view conversion, if the target type and the operand type do not
+   have a common ancestor, then the component subtype shall not have a private
+   or visibly by-reference subcomponent.
+
+I haven't posted this yet. I figured I'd wait for all of the good things Tucker
+is finishing up... (hope I'm not waiting for Godot :-)
+
+****************************************************************
+
+From: Robert A Duff
+Sent: Wednesday, November 08, 2000 9:30 AM
+
+> In any case, the issues are closely related (conversions that cannot be
+> performed if there is a representation change). So I don't see why we would
+> want to consider them separately, potentially solving them in different
+> ways.
+
+I agree -- keep it as one AI.
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent