CVS difference for ai05s/ai05-0050-1.txt
--- ai05s/ai05-0050-1.txt 2007/05/05 01:39:15 1.1
+++ ai05s/ai05-0050-1.txt 2007/10/31 02:24:49 1.2
@@ -1,4 +1,4 @@
-!standard 6.5(24/2) 07-05-04 AI05-0050-1/01
+!standard 6.5(24/2) 07-10-30 AI05-0050-1/02
!class binding interpretation 07-05-04
!status work item 07-05-04
!status received 07-04-20
@@ -9,18 +9,6 @@
!summary
-*TBD*
-
-!question
-
-Should the implementation permissions of 6.5(24/2) be revised? The current permission
-both requires inefficient implementations in some cases and also allows an exception to
-be raised in cases where no exception would be raised without the permission.
-
-!recommendation
-
-(Recommended in e-mail discussion:)
-
If an object is being initialized by a function call and the implementation
can tell before the call that the object subtype and the function result
subtype are incompatible, then the implementation should be permitted
@@ -37,10 +25,186 @@
All of these permissions apply to recursive calls (that is, calls to a function in
a return statement).
+!question
+
+Should the implementation permissions of 6.5(24/2) be revised? The current permission
+both requires inefficient implementations in some cases and also allows an exception to
+be raised in cases where no exception would be raised without the permission.
+
+!recommendation
+
+(See summary.)
+
!wording
+
+Replace 6.5(24/2)
-*TBD*
+ If the result subtype of a function is unconstrained, and a call on the
+ function is used to provide the initial value of an object with a
+ constrained nominal subtype, Constraint_Error may be raised at the point
+ of the call (after abandoning the execution of the function body) if,
+ while elaborating the return_subtype_indication or evaluating the expression
+ of a return statement that applies to the function body, it is determined
+ that the value of the result will violate the constraint of the subtype
+ of this object.
+
+with
+
+ If a call on a function is used to provide the initial value of an object
+ of a composite type, then certain actions which would be performed
+ after the evaluation of the function call according to the canonical
+ semantics may be performed earlier.
+
+ Consider the following three points at which the constraints of the
+ function result may become known:
+ - before calling the function
+ (in the case where the function result subtype is constrained)
+
+ - during the elaboration of the return object declaration of an
+ extended_return_statement of the function
+
+ - during the evaluation of the expression of a simple_return_statement
+ of the function
+ .
+
+ If, at any of these points, it is determined that the function result
+ value will violate either the constraint of the subtype of the object
+ or some other intermediate constraint that would be checked during the
+ initialization of the object, then Constraint_Error may be raised at that
+ point.
+
+ If the function call is used to provide the initial value of an
+ initialized allocator, then any calls to System.Storage_Pools.Allocate
+ (or System.Storage_Pools.Deallocate) which are associated with the
+ allocation of the object may be performed at any of these points, or at the
+ point of a non-value-returning exit from an extended return statement of the
+ function.
+
+ These permissions do not apply in the case of an extended_return_statement
+ where the function result object is discriminated and is not known to be
+ constrained.
+
+ AARM Notes
+
+ These permissions apply transitively in the case of a function call
+ which returns the value of another function call. In the following example,
+
+ declare
+ type T is
+ limited record
+ ... ;
+ end record;
+ -- requires in-place initialization
+ type Unconstrained is array (Positive range <>) of T;
+
+ function Some_Function return T is ... ;
+
+ function F1 return Unconstrained is
+ begin
+ return (1 .. 10 => Some_Function);
+ end F1;
+
+ function F2 return Unconstrained is
+ begin
+ return F1;
+ end F2;
+
+ X : Unconstrained (1..3) := F2;
+ begin
+ null;
+ end;
+
+ , Constraint_Error may be raised in F1 before any calls to Some_Function
+ are executed.
+
+ The "intermediate constraint" wording refers to cases like
+
+ declare
+ type T is
+ limited record
+ ... ;
+ end record;
+ -- requires in-place initialization
+
+ type Unconstrained is array (Positive range <>) of T;
+
+ subtype Constrained is T (1 .. 3);
+
+ function Some_Function return T is ... ;
+
+ function F1 return Unconstrained is
+ begin return (1.. 10 => Some_Function); end;
+
+ function F2 return Constrained is begin return F1; end if;
+
+ function F3 return Unconstrained is
+ begin
+ return Constrained'(F1);
+ end F3;
+
+
+ begin
+ begin
+ declare
+ X : Unconstrained := F2;
+ begin null; end;
+ exception when Constraint_Error => null;
+ end;
+
+ begin
+ declare
+ X : Unconstrained := F3;
+ begin null; end;
+ exception when Constraint_Error => null;
+ end;
+
+ begin
+ declare
+ X : Unconstrained := Constrained'(F1);
+ begin null; end;
+ exception when Constraint_Error => null;
+ end;
+ end;
+
+ In all three of these cases, Constraint_Error may be raised in F1 before
+ the execution of any calls to Some_Function.
+
+ The "These permissions do not apply" clause handles the
+ case of an extended return object with mutable discriminants.
+ Because of this clause, the permissions of this section do not apply in
+ the following example
+
+ declare
+ type T (Is_Big : Boolean := True) is
+ record
+ case Is_Big is
+ when False => null;
+ when True => Big_Component : String (1..1024) := (others => 'X');
+ end case;
+ end record;
+
+ function F return T is
+ begin
+ return X : T do
+ X.Big_Component := (others => 'Y');
+ X := (Is_Big => False);
+ end return;
+ end F;
+
+ Small_Object : T (Is_Big => False) := F;
+ begin
+ null;
+ end;
+
+ and so Constraint_Error may not be raised (which is good).
+
+ Note that this revocation of permissions only applies in cases where
+ in-place initialization is optional. This means that any difficulties
+ associated with implementing in-place initialization without these
+ permissions can be sidestepped.
+
+
!discussion
The implementation permissions of 6.5(24/2) do not go far enough.
@@ -230,7 +394,81 @@
#3 could be viewed as requiring only a clarification of the current
wording.
+----
+
+It has been argued that these permissions are already implied by
+11.6 and therefore do not need to be repeated. This is simply not the case.
+For example, the permissions given in this section allow a constraint check
+to be moved into an independent subprogram. 11.6 alone would not allow this.
+
+This is necessary to support allocation of function result objects by
+compiler-generated callback routines, where the caller of a function
+passes in a reference to a storage allocation routine which
+is invoked when the constraints of the function result are known.
+If a constraint check performed by the callback routine fails, this
+appears to the user as though Constraint_Error were raised at the point
+where the callback routine was called (i.e., within the function).
+If the function in question is an independent subprogram, this means
+that the constraint check has been moved into an independent subprogram.
+
+Even if the permissions of this section were redundant, they should still
+be stated explicitly here for the sake of the clarity of the language
+definition. Reliance on these permissions is effectively required in the cases
+where in-place initialization is required. Section 11.6 is about permissions
+which enable optional optimizations - an implementer should have
+the option of completely ignoring 11.6. Permissions which are
+needed in order to correctly implement the language should be stated
+outside of 11.6 .
+
+----
+
+The original wording of 6.5(24/2) applied in the case of a scalar result
+type. This seems wrong. Do we really want this paragraph to apply in the
+case of a function whose result subtype is Standard.Float? No.
+That is why the revised wording includes the phrase "of a composite type".
+This permission refers to dynamic semantics, so there are no issues with
+privacy.
+
+----
+The mention of System.Storage_Pools.Deallocate is needed to allow
+implementations to avoid storage leaks. Consider the following example:
+
+ declare
+ type T is
+ limited record
+ ... ;
+ end record;
+ -- requires in-place initialization
+
+ type Unconstrained is array (Positive range <>) of T;
+
+ function F1 return Unconstrained is
+ Result_Length : Natural := 10;
+ begin
+ for Really_Return in Boolean loop
+ Result_Length := Result_Length * 2;
+ return Result : Unconstrained (1 .. Result_Length) do
+ ...;
+ if not Really_Return then goto L;
+ end return;
+ <<L>> null;
+ end loop;
+ end F1;
+
+ type Unconstrained_Ref is access Unconstrained;
+ for Unconstrained_Ref'Storage_Pool use ... ;
+
+ Ptr : Unconstrained_Ref := new Unconstrained'(F1);
+ begin
+ ...;
+ end;
+
+The execution of this example may involve two calls to
+System.Storage_Pools.Allocate. We do not want to require that implementations
+clean up after the first call by calling Deallocate,
+but we do want to give implementations that option.
+
!ACATS test
@@ -673,3 +911,26 @@
****************************************************************
+From: Randy Brukardt
+Sent: Tuesday, October 30, 2007 7:10 PM
+
+[Commenting on version /02 of the AI.]
+
+I don't see much problem with allowing this permission for scalar types
+(although I doubt it would be used much).
+
+The issue with Deallocate is just the tip of the iceberg; any object that
+needs finalization has similar issues if it gets constructed far enough to
+"exist", as there is no permission to do the finalization early. That's
+touched on in another AI (AI05-0066-1), although I suspect that we'll end up
+with a solution that doesn't fix it. I think any object that is "inaccessible"
+should be able to be finalized at the leaving of any master (so long as it
+doesn't contain any tasks that haven't terminated -- waiting for tasks at
+random points would be a no-no). The reason for restricting to the leaving
+of any master prevents Finalize from being called in the middle of an operation
+(it shouldn't be necessary to protect it against multitasking issues in an
+otherwise single-tasking environment). A similar permission for Deallocate
+is also needed. I don't see any reason to clutter this one spot with something
+that needs to cover the entire language.
+
+****************************************************************
Questions? Ask the ACAA Technical Agent