CVS difference for ai05s/ai05-0032-1.txt

Differences between 1.3 and version 1.4
Log of other versions for file ai05s/ai05-0032-1.txt

--- ai05s/ai05-0032-1.txt	2007/11/07 06:32:42	1.3
+++ ai05s/ai05-0032-1.txt	2007/12/13 04:39:35	1.4
@@ -1,5 +1,10 @@
-!standard  6.5(5.2/2)                                         07-05-18    AI05-0032-1/01
-!class Amendment 06-11-19
+!standard  6.5(5.2/2)                                         07-11-11    AI05-0032-1/02
+!standard  6.5(5.3/2)
+!standard  6.5(5.6/2)
+!standard  6.5(5.8/2)
+!standard  6.5(8/2)
+!class binding interpretation 07-11-11
+!status ARG Approved  7-1-1  06-11-11
 !status work item 06-11-19
 !status received 06-11-19
 !priority Medium
@@ -8,12 +13,11 @@
 
 !summary
 
-(See proposal.)
+If a function returns a class-wide type, the object of an extended_return_statement
+can be declared with a specific type that is covered by the class-wide type.
 
-!problem
+!question
 
-!proposal
-
 Imagine a device driver that registers a constructor function when it is loaded.
 The constructor function returns Device'Class. Device is a limited type.
 
@@ -23,24 +27,28 @@
     return Obj : <specific type> do -- Not legal
     
 This is not legal because we require the type here to be the same as that of the
-function [defined in 6.5(5.2/2)]. Instead, you have to write: 
+function [defined in 6.5(5.2/2)]. Instead, you have to write something like: 
 
     return Obj : Device'Class := Func do 
     
-where Func is a dispatching call. 
+where the result type of Func is the desired specific tagged type. 
 
-It seems that the first case really should be legal.  An alternative view
+It seems that the first case really should be legal. An alternative view
 suggests that the example is inappropriate; a constructor should be a
-dispatching function, not something returning a classwide type.   You could
+dispatching function, not something returning a classwide type. You could
 write a factory this way, but the actual constructs should probably still be
 dispatching routines. However, arguments from usage patterns are difficult to
 decide. Note that this is somewhat similar to the unconstrained case, where we
-allow giving constraints.  For example:
+allow giving constraints. For example:
 
     function F return String is
     begin
          return Obj : String(1..10) do ...
 
+!recommendation
+
+(See summary.)
+
 !wording
 
 Modify RM 6.5(5.2/2) as follows:
@@ -54,11 +62,24 @@
     unconstrained, then the subtype defined by the subtype_indication shall be a
     definite subtype, or there shall be an expression.
     
+Append after 6.5(5.3/2) (as a new item in the same bulleted list):
+   * If the result subtype of the function is class-wide, the accessibility level
+     of the type of the subtype defined by the return_subtype_indication
+     shall not be statically deeper than that of the master that elaborated
+     the function body.     
+
+Modify 6.5(5.6/2) as follows:
+   * If the result subtype of the function is class-wide, the accessibility level of
+     the type of the expression {(if any)} of the return statement...
+
 Add to the end of RM 6.5(5.8/2):
+
+    ... {A check is made that the value of the return object belongs to the function
+    result subtype. Constraint_Error is raised if this check fails.}
 
-    ... {If the result type is class-wide, a view conversion of the return
-    object to the function result subtype is evaluated Redundant:[, which might
-    raise Constraint_Error].}
+    AARM Ramification: Other rules ensure that this check cannot fail unless
+    the function has a class-wide result subtype where the associated specific
+    subtype is constrained. 
   
 Modify RM 6.5(8/2) as follows:
 
@@ -70,54 +91,42 @@
     of the result is not deeper than that of the master that elaborated the
     function body. If this check fails, Program_Error is raised.
     
-Modify RM 6.5(23/2) as follows:
-
-    In the case of a function, the function_call denotes a constant view of the
-    return object.  {If the result type is class-wide, this view is that created
-    by the view conversion of the return object to the function result subtype
-    (see above).}
-
 !discussion
 
-The example in the "problem" section above illustrates how the existing rule can
-be annoying.  Arguing from consistency with the existing ability to specify a
+The example in the "question" section above illustrates how the existing rule can
+be annoying. Arguing from consistency with the existing ability to specify a
 more constrained subtype in the return_subtype_indication, it seems reasonable
 to allow an object of any type that would satisfy the "expected type" for the
-expression in a simple_return_statement.  The expected type for that expression
-is the function result type.  That means that if the function result type is
+expression in a simple_return_statement. The expected type for that expression
+is the function result type. That means that if the function result type is
 class-wide, then the return expression in a simple_return_statement could be of
-any type covered by the class-wide type.  It seems reasonable therefore to allow
+any type covered by the class-wide type. It seems reasonable therefore to allow
 the declaration of an object of any such type as the return object in an
 extended_return_statement.
 
 Note that the main wording changes are quite simple, namely adding "covered by"
 to paragraph 5.2/2, and specifying that the tag comes from the subtype_
 indication if it is specifc. 
+
+We also need a rule to handle static rejection for accessibility failure of cases
+like
+
+  function Foo return T'Class is
+    type Local_Extension is new T with null record;
+  begin
+    return X : Local_Extension;
+  end Foo;
+
+Associated with that is the addition of "(if any)" to 6.5(5.6/2), since an expression
+is no longer required in an extended return (since a specific type can be given).
 
-The changes in 5.8/2 and 23/2 are actually patching a hole that already existed,
+The change in 5.8/2 is actually patching a hole that already existed,
 since one could have a result subtype of "S1'Class" but specify a nominal
 subtype for the return object of "S2'Class" where S1 and S2 are both subtypes of
 the same type, and nowhere were we checking that the return object satisfied the
 constraints of S1.
 
-Actually, there is a bigger problem here, because it appears that in 4.6 (Type
-Conversions) we don't ever do the discriminant check you would expect if you
-convert S2'Class to S1'Class.  The relevant sentence would be the first sentence
-of RM 4.6(51/2):
-  
-    After conversion of the value to the target type, if the target subtype is
-    constrained, a check is performed that the value satisfies this
-    constraint...
-
-Unfortunately, all subtypes of a class-wide type are considered unconstrained,
-because they have unknown discriminants.  Furthermore, I'm not sure we ever
-specify what it means to "satisfy" the constraint associated with S1'Class,
-though it probably wouldn't be too hard if we first do a view conversion to 
-the type of S1, and then check the discriminants of that view against the
-constraints of S1.
-
-So the changes suggested above for 6.5(5.8,23) are sort of irrelevant if we
-don't also add something to 4.6(51).  That should probably be a separate AI.
+!example
 
     -- Every device kind needs a constructor that creates a device control
     -- block for that kind of device.  This constructor is registered
@@ -142,6 +151,113 @@
   begin
     Register_Device_Constructor(My_Device_Kind, Make_My_Device'Access);
 
+!corrigendum 6.5(5.2/2)
+
+@drepl
+@xbullet<If the result subtype of the function is defined by a
+@fa<subtype_mark>, the @fa<return_subtype_indication> shall be a
+@fa<subtype_indication>. The type of the @fa<subtype_indication> shall be the
+result type of the function. If the result subtype of the function is
+constrained, then the subtype defined by the @fa<subtype_indication> shall also
+be constrained and shall statically match this result subtype. If the result
+subtype of the function is unconstrained, then the subtype defined by the
+@fa<subtype_indication> shall be a definite subtype, or there shall be an
+@fa<expression>.>
+@dby
+@xbullet<If the result subtype of the function is defined by a
+@fa<subtype_mark>, the @fa<return_subtype_indication> shall be a
+@fa<subtype_indication>. The type of the @fa<subtype_indication> shall be covered by
+the result type of the function. If the result subtype of the function is
+constrained, then the subtype defined by the @fa<subtype_indication> shall also
+be constrained and shall statically match this result subtype. If the result
+subtype of the function is unconstrained, then the subtype defined by the
+@fa<subtype_indication> shall be a definite subtype, or there shall be an
+@fa<expression>.>
+
+!corrigendum 6.5(5.3/2)
+
+@dinsa
+@xbullet<If the result subtype of the function is defined by an
+@fa<access_definition>, the @fa<return_subtype_indication> shall be an
+@fa<access_definition>. The subtype defined by the @fa<access_definition> shall
+statically match the result subtype of the function. The accessibility level of
+this anonymous access subtype is that of the result subtype.>
+@dinst
+@xbullet<If the result subtype of the function is class-wide, the accessibility level
+of the type of the subtype defined by the @fa<return_subtype_indication>
+shall not be statically deeper than that of the master that elaborated
+the function body.>
+
+!corrigendum 6.5(5.6/2)
+
+@drepl
+@xbullet<If the result subtype of the function is class-wide, the
+accessibility level of the type of the @fa<expression> of the return statement
+shall not be statically deeper than that of the master that elaborated the
+function body. If the result
+subtype has one or more unconstrained access discriminants, the
+accessibility level of the anonymous access type of each access discriminant,
+as determined by the @fa<expression> of the @fa<simple_return_statement> or the
+@fa<return_subtype_indication>, shall not be statically deeper than that of the
+master that elaborated the function body.>
+@dby
+@xbullet<If the result subtype of the function is class-wide, the
+accessibility level of the type of the @fa<expression> (if any) of the
+return statement shall not be statically deeper than that of the master
+that elaborated the function body. If the result
+subtype has one or more unconstrained access discriminants, the
+accessibility level of the anonymous access type of each access discriminant,
+as determined by the @fa<expression> of the @fa<simple_return_statement> or the
+@fa<return_subtype_indication>, shall not be statically deeper than that of the
+master that elaborated the function body.>
+
+!corrigendum 6.5(5.8/2)
+
+@drepl
+For the execution of an @fa<extended_return_statement>, the
+@fa<subtype_indication> or @fa<access_definition> is elaborated. This creates
+the nominal subtype of the return object. If there is an @fa<expression>, it
+is evaluated and converted to the nominal subtype (which might raise
+Constraint_Error @emdash see 4.6);
+the return object is created and the converted value is assigned to
+the return object. Otherwise, the return object is created and initialized
+by default as for a stand-alone object of its nominal subtype (see 3.3.1).
+If the nominal subtype is indefinite, the
+return object is constrained by its initial value.
+@dby
+For the execution of an @fa<extended_return_statement>, the
+@fa<subtype_indication> or @fa<access_definition> is elaborated. This creates
+the nominal subtype of the return object. If there is an @fa<expression>, it
+is evaluated and converted to the nominal subtype (which might raise
+Constraint_Error @emdash see 4.6);
+the return object is created and the converted value is assigned to
+the return object. Otherwise, the return object is created and initialized
+by default as for a stand-alone object of its nominal subtype (see 3.3.1).
+If the nominal subtype is indefinite, the
+return object is constrained by its initial value.
+A check is made that the value of the return object belongs to the function
+result subtype. Constraint_Error is raised if this check fails.
+
+!corrigendum 6.5(8/2)
+
+@drepl
+If the result type of a function is a specific
+tagged type, the tag of the return object is that
+of the result type. If the result type is class-wide, the tag of the
+return object is that of the value of the expression. A check is made that
+the accessibility level of the type identified by the tag of the result is
+not deeper than that of the master that elaborated the function body. If
+this check fails, Program_Error is raised.
+@dby
+If the result type of a function is a specific
+tagged type, the tag of the return object is that
+of the result type. If the result type is class-wide, the tag of the
+return object is that of the type of the @fa<subtype_indication>
+if it is specific, or otherwise that of the value of the @fa<expression>. A check is made that
+the accessibility level of the type identified by the tag of the result is
+not deeper than that of the master that elaborated the function body. If
+this check fails, Program_Error is raised.
+
 !ACATS test
 
 Create an ACATS test to check that the above changes work.
@@ -236,5 +352,109 @@
 
 Good point, Randy.  AI05-0032 should be amended
 instead of adding it to this AI.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, December 3, 2007  11:59 PM
+
+At the recent meeting, I objected to the proposed added wording for 6.5(23/2):
+
+    In the case of a function, the function_call denotes a constant view of the
+    return object. {If the result type is class-wide, this view is that created
+    by the view conversion of the return object to the function result subtype
+    (see above).}
+
+I originally said that I thought this addition was redundant. Tucker gave his
+reason for including it as "the return object has a specific type, and the caller
+needs to see a different view". I was concerned that there was something wrong
+with this, but we pushed on to a vote without much additional consideration. (I
+have the feeling that my concerns weren't taken particularly seriously because
+of my previous objection to the entire concept; while they were totally unrelated
+to that, I can imagine how some people may have felt I was just trying to obstruct
+completing the AI.)
+
+Anyway, I'm still convinced that either this text is completely redundant, or
+there is something seriously wrong with the language. (I think it is the former,
+but I could be wrong.)
+
+My basic point is that while objects may have a nominal class-wide subtype, they
+never have a real type that is class-wide. That is, the actual object always has
+some specific tagged type. We don't worry in the Standard where that class-wide
+view comes from; it just appears when needed (like many other kinds of views).
+
+So I don't think we need special wording to cover this case.
+
+More specifically, an extended_return_statement has rather similar semantics to
+an allocator (which, BTW, is one of the best arguments for this AI in general).
+Consider that:
+
+     function F ... return T'Class is
+         ...
+         return Obj : T do ...
+
+is very similar to
+
+     type Any_T is access all T'Class;
+     Ptr : Any_T := new T;
+
+But I can't find any wording in 4.8 that says that the object created by "new T"
+is view converted to the designated type and that this is the view accessed by the
+designated type. I presume that is because it isn't necessary; any access through
+the access type will have the right view (a class-wide type), even though the
+object itself still has a specific type.
+
+And the same is true for a function call; any reference of the return object after
+the return of the function will have a class-wide nominal subtype, and that is
+fine and expected. Before the return (within the extended return statement),
+the object will have the nominal subtype it was declared with, and that too is
+expected.
+
+The only issue I can think of is if the class-wide type is partially constrained,
+and a constraint check is needed -- but that is separate from the class-wide view.
+Moreover, the rule added to 6.5(5.8/2) takes care of the needed conversion. (I
+wouldn't call it a conversion, just a check, but that's nit-picking.)
+
+So I still don't see the point of this extra wording; it just seems to confuse
+the issue by seeming to say that something else is going on than the normal case.
+And this is just the normal case for class-wide objects (as noted above for
+allocators, and also is the normal case for class-wide object declarations).
+Why is this case different??
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, December 4, 2007  12:29 AM
+
+The discussion of AI-32 seems to imply that the only reason for 6.5(5.8/2)
+and 6.5(23/2) is to make this check. (There also was a lot of irrelevant
+junk that pertains to AI-57 rather than AI-32, which I deleted.) In that
+case, I don't know why we aren't just using similar wording to allocators -
+4.8(10/2) says: "A check is made that the value of the object belongs to the
+designated subtype."  Seems to me that 4.8(5.8/2) should just say:
+   "If the result type is class-wide, a check is made that the value of the
+object belongs to the function result subtype."
+...and then no change to 4.8(23/2) is needed.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, December 4, 2007  6:05 AM
+
+I presume you meant 6.5(5.8/2), not 4.8(5.8/2).
+And I agree, adding explicit wording, as you suggest here,
+about a check would seem to address the primary concern.
+Your suggested addition could say simply "A check is made..."
+and not bother with the "class-wide" prerequisite, since
+the check is certain to succeed in other cases.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, December 4, 2007  2:21 PM
+
+OK. I'll use this wording in the final AI (as an "editorial review" change)
+unless someone objects. (If someone objects, we'll have to discuss it at a
+meeting again.)
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent