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

Differences between 1.5 and version 1.6
Log of other versions for file ai05s/ai05-0177-1.txt

--- ai05s/ai05-0177-1.txt	2010/10/26 05:28:25	1.5
+++ ai05s/ai05-0177-1.txt	2010/11/20 07:47:30	1.6
@@ -1,4 +1,4 @@
-!standard  3.1(3/2)                               10-10-21    AI05-0177-1/04
+!standard  3.1(3/2)                               10-11-19    AI05-0177-1/05
 !standard  3.11.1(1/1)
 !standard  6.1(20)
 !standard  6.1(30)
@@ -11,7 +11,10 @@
 !standard  8.3.1(3/2)
 !standard  13.14(8/1)
 !standard  13.14(10.1/3)
+!standard  13.14(10.2/3)
 !class Amendment 09-10-29
+!status Amendment 2012 10-11-19
+!status ARG Approved  8-0-2  10-10-29
 !status work item 09-10-29
 !status received 09-03-15
 !priority Medium
@@ -20,9 +23,11 @@
 !summary
 
 An expression function can define the body of a function, even in a package
-specification. They act like default expressions for
-freezing and evaluation purposes.
+specification. They act like default expressions for freezing and evaluation
+purposes.
 
+A null procedure can be a completion.
+
 !problem
 
 With the advent of pre and postconditions (see AI05-0145-1), and conditional
@@ -86,7 +91,7 @@
 
 Modify the last sentence of 3.11.1(1/1):
 
-A body is a body, an entry_body, {a null_procedure_declaration or an
+A body is a body, an entry_body, {a null_procedure_declaration or 
 expression_function_declaration that completes another declaration}, or a
 renaming-as-body (see 8.5.4).
 
@@ -96,11 +101,16 @@
 null_procedure_declaration (see 6.7){, or an expression_function_declaration
 (see 6.8)}.
 
-Add to the end of 6.1(30):
+Modify 6.1(30):
 
-Finally, a function defined by an expression_function_declaration is an
+A subprogram declared by an abstract_subprogram_declaration is abstract; a
+subprogram declared by a subprogram_declaration is not. See 3.9.3, “Abstract
+Types and Subprograms”. Similarly, a procedure {declared}[defined] by a
+null_procedure_declaration is a null procedure; a procedure declared by
+a subprogram_declaration is not. See 6.7, “Null Procedures”. 
+{Finally, a function declared by an expression_function_declaration is an
 expression function; a function declared by a subprogram_declaration is not. See
-6.8, "Expression Functions".
+6.8, "Expression Functions".}
 
 [Note: The following three changes are needed to allow null procedures as
 completions; see the discussion for why this is needed.]
@@ -109,8 +119,7 @@
 
 Legality Rules
 
-A null_procedure_declaration need not be the completion of a previous
-declaration, but if a null_procedure_declaration is a completion, it shall be
+If a null_procedure_declaration is a completion, it shall be
 the completion of a subprogram_declaration or generic_subprogram_declaration.
 The profile of a null_procedure_declaration that completes a declaration shall
 conform fully to that of the declaration.
@@ -127,7 +136,7 @@
 Modify 6.7(5/2):
 
 The elaboration of a null_procedure_declaration has no {other} effect {than to
-establish that the expression function can be called without failing the
+establish that the null procedure can be called without failing the
 Elaboration_Check}.
 
 Add a new clause:
@@ -135,32 +144,31 @@
 6.8 Expression functions
 
 An expression_function_declaration provides a shorthand to declare a function
-that returns a single expression.
+whose body consists of a single return statement.
 
 Syntax
 
 expression_function_declaration ::=
    [overriding_indicator]
    function_specification is
-      (*parameterized_*expression)
+      (expression)
       [aspect_specification];
 
 Name Resolution Rules
 
-The expected type for the *parameterized_*expression of an
+The expected type for the expression of an
 expression_function_declaration is the result type (see 6.5) of the function.
 
 Legality Rules
 
-An expression_function_declaration need not be the completion of a previous
-declaration, but if an expression_function_declaration is a completion, it shall
+If an expression_function_declaration is a completion, it shall
 be the completion of a subprogram_declaration or generic_subprogram_declaration.
 The profile of an expression_function_declaration that completes a declaration
 shall conform fully to that of the declaration.
 
 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 *paarameterized_*expression, shall not be statically deeper
+determined by the expression of the expression function, shall not be statically deeper
 than that of the master that elaborated the expression_function_declaration.
 
 AARM Ramification: This can only fail if the discriminant is an access to a part
@@ -171,7 +179,7 @@
 statement has to apply to this function (and isn't nested in something), there
 clearly is a return statement in this function, and the static classwide
 accessibility check cannot fail as a tagged type cannot be declared locally in
-this function.]
+an expression function.]
 
 Static Semantics
 
@@ -184,7 +192,7 @@
 The execution of an expression function is invoked by a subprogram call. For the
 execution of a subprogram call on an expression function, the execution of the
 subprogram_body is equivalent to a function body containing only a
-simple_return_statement that returns the *parameterized_*expression.
+simple_return_statement whose expression is that of the expression function.
 
 AARM Discussion: The last sentence effectively means that all of the dynamic
 wording in 6.5 applies as needed, and we don't have to repeat it here.
@@ -200,7 +208,7 @@
 
 Add new bullet after 7.5(2.8/2):
 
-* the *parameterized_*expression of an expression_function_declaration (see 6.8)
+* the expression of an expression_function_declaration (see 6.8)
 
 Modify 8.3(18/2):
 
@@ -210,7 +218,7 @@
   visibility only until the reserved word is of the declaration;.
 
 [Editor's note: We need this to make the parameters visible in the
-*parameterized_*expression of an expression_function_declaration.]
+expression of an expression_function_declaration.]
 
 Add expression_function_declaration into the list of 8.3.1(3/2), after
 null_procedure_declaration.
@@ -219,7 +227,7 @@
 
 A static expression causes freezing where it occurs. An object name or nonstatic
 expression causes freezing where it occurs, unless the name or expression is
-part of a default_expression, a default_name, {the *parameterized_*expression of
+part of a default_expression, a default_name, {the expression of
 an expression function,} or a per-object expression of a component's constraint,
 in which case, the freezing occurs later as part of another construct.
 
@@ -228,16 +236,51 @@
 At the place where a function call causes freezing, the profile of the function
 is frozen. Furthermore, if a parameter of the call is defaulted, the
 default_expression for that parameter causes freezing. {If the function call is
-to an expression function, the *parameterized_*expression for the expression
+to an expression function, the expression of the expression
 function causes freezing.}
 
-AARM Ramification: Freezing of the *parameterized_*expression only needs to be
-considered when the expression function is in the same compilation unit and
+AARM Ramification: Freezing of the expression of an expression function only needs
+to be considered when the expression function is in the same compilation unit and
 there are no intervening bodies; the end of a declarative_part or library
 package freezes everything in it, and a body freezes everything declared before
 it.
 
+Modify 13.14(10.2/3) [as added by AI05-0019-1]:
+
+At the place where a generic_instantiation causes freezing of a callable entity,
+the profile of that entity is frozen{; if the callable entity is an expression
+function, the expression of the expression function causes freezing}.
+
+Add after 13.14(10.2/3):
+
+At the place where a use of the Access or Unchecked_Access attribute whose prefix
+denotes an expression function causes freezing, the expression of the expression
+function causes freezing.
+
+AARM Reason:
+
+This is needed to avoid calls to unfrozen expressions. Consider:
+
+      package Pack is
+
+          type Flub is range 0 .. 100;
+
+          function Foo (A : in Natural) return Natural is
+              (A + Flub'Size); -- The expression is not frozen here.
+
+          type Bar is access function Foo (A : in Natural) return Natural;
+
+          P : Bar := Foo'Access; -- (A)
 
+          Val : Natural := P.all(5); -- (B)
+
+      end Pack;
+
+If point (A) did not freeze the expression of Foo (which freezes Flub), then
+the call at point (B) would be depending on the aspects of the unfrozen type Flub.
+That would be bad.
+End AARM Reason.
+
 !discussion
 
 Naming:
@@ -268,6 +311,60 @@
 represent a completion. This is not an important capability, but it increases
 the consistency of the various kinds of subprogram declaration.
 
+Note that both null subprograms and expression functions are freeze when they
+are used as completions. There are a number of reasons for this:
+
+(1) This is consistent with the behavior of explicit bodies. If the null procedure
+or expression function replace the equivalent explicit body, the freezing will
+not change.
+
+(2) If a null procedure used as a completion did not freeze, then AARM 13.14(10.f/3)
+would not be true. There would be a way to construct a program that made a procedure
+call with an unfrozen profile - admittedly, a pathological program (it could only have
+null procedure bodies). (That could be fixed by extending 13.14(10.1/3) to all
+subprograms.)
+
+(3) If an expression function used as a completion did not freeze, then it would
+be possible to make a call to an expression function with an unfrozen expression.
+Consider:
+
+      package Pack is
+          function Foo (A : in Natural) return Natural;
+          type Bar is access function Foo (A : in Natural) return Natural;
+
+          P : Bar := Foo'Access; -- Freezes Bar and Foo.
+
+          type Flub is range 0 .. 100;
+
+          function Foo (A : in Natural) return Natural is
+              (A + Flub'Size); -- The expression is not frozen here.
+
+          Val : Natural := P.all(5); -- (!)
+
+      end Pack;
+
+The call of P.all passes the elaboration check (as the completion of Foo has been
+elaborated). However, if the body of Foo did not freeze everything, Flub would
+not be frozen, and thus the call P.all(5) would be evaluating the value of an aspect of
+an unfrozen type.
+
+Note that the prefix of Foo freezes the declaration of Foo, but not the (still to
+be seen) completion; and even if the completion was frozen, that would not freeze
+the expression.
+
+(1) here is not a big deal, but (2) and (3) must be addressed if we later decide this
+is too limiting. [Editor's note: this strikes me as killing a fly with a bazooka,
+given that neither of these problems is likely to occur in practice, but the early
+freezing is likely to bite lots of users. OTOH, there is not an obvious fix
+other than this for problem (3).
+
+The best idea I've had that did not envolve freezing all completions would be to
+freeze the expression of an expression function used as a completion at the point
+of the completion if the subprogram has been used as generic formal parameter or
+as the prefix of 'Access. Seems like a mess. A regular call would not need a
+special rule, as either it is before the completion (and the elaboration check
+would fail), or it calls the completion directly, which is already covered.]
+
 ---
 
 One could imagine these functions (when visible) to be used in static
@@ -313,6 +410,72 @@
 !ACATS test
 
 Add an ACATS C-Test to test the syntax.
+
+!ASIS
+
+Modify function Is_Null_Procedure:
+
+Add a A_Procedure_Body_Declaration to the list of Kinds.
+
+
+Add after Is_Null_Procedure (12.49):
+
+function Is_Expression_Function
+    function Is_Expression_Function
+     (Element : in Asis.Element)
+      return Boolean;
+
+Element specifies the element to query.
+
+Returns True for a declaration of a function that is declared as an expression function.
+
+Returns False for any other Element including Nil_Element.
+
+Element expects an element that has the following Element_Kinds: 
+A_Declaration
+that has one of the following Declaration_Kinds: 
+A_Function_Declaration
+A_Function_Body_Declaration
+
+Usage Note: This routine tests for the syntactic element expression_function_declaration;
+calling Is_Expression_Function on a renaming of an expression function will return False.
+Use the routine ASIS.Callable_Views.Is_Expression to determine if a declaration is semantically
+an expression function (including renames). 
+
+Discussion: A generic function cannot be an expression function.
+
+Add after Result_Subtype, 14.19:
+
+function Expression_Function_Expression (Declaration : in Asis.Declaration)
+              return Asis.Expression;
+
+      Declaration specifies the expression function to query.
+
+      Returns the expression in the expression function declaration.
+
+      Declaration expecrs an element that has the following Element_Kinds: 
+         A_Declaration
+         that has one of the following Declaration_Kinds: 
+            A_Function_Declaration
+            A_Function_Body_Declaration
+
+      Raises ASIS_Inappropriate_Element with a Status of Value_Error for any element
+      that does not have these expected kinds.
+
+      Returns an element that the following Element_Kinds: 
+         An_Expression
+
+
+Add to 21.10.3 Callable view categorization
+
+After Is_Null:
+
+function Is_Expression (C : Callable_View) return Boolean is abstract;
+
+After Is_Null's description:
+
+Is_Expression returns True if the Callable_View denotes an Expression Function, and returns
+False otherwise.
 
 !appendix
 

Questions? Ask the ACAA Technical Agent