CVS difference for ai12s/ai12-0175-1.txt
--- ai12s/ai12-0175-1.txt 2015/10/09 01:57:41 1.1
+++ ai12s/ai12-0175-1.txt 2015/10/13 01:56:24 1.2
@@ -1,4 +1,4 @@
-!standard 10.2.1(7) 15-10-08 AI05-0175-1/00
+!standard 4.9(1) 15-10-08 AI05-0175-1/01
!standard 13.7.1(10/3)
!class Amendment 15-10-08
!status work item 15-10-08
@@ -8,7 +8,8 @@
!subject Preelaborable packages with address clauses
!summary
-** TBD.
+Add aspects so that sufficiently simple composite types (including private
+types) and functions of those can be treated as static.
!problem
@@ -43,11 +44,294 @@
!wording
-** TBD.
+[Editor's note: I didn't try to update the existing AARM notes; that will need
+to be done.]
+Modify 4.9(1):
+
+Certain expressions of a {potentially static}[scalar or string] type are
+defined to be static. Similarly, certain discrete ranges are defined to be
+static, and certain {potentially static}[scalar or string] subtypes are
+defined to be static subtypes. [ Static means determinable at compile time,
+using the declared properties or values of the program entities.]
+
+{A *potentially static* type is either a scalar type, a string type, or a
+composite type for which the Potentially_Static aspect is True.}
+
+Static Semantics
+
+For a composite type, the following language-defined aspect may be
+specified with an aspect_specification (see 13.1.1):
+
+Potentially_Static The type of aspect Potentially_Static is Boolean.
+If directly specified, the aspect_definition shall be a static expression.
+If not specified (including by inheritance), the aspect is False.
+
+[Editor's note: Legality Rules for this aspect are below, after paragraph 37.
+The meaning was given in the paragraph preceding this definition.]
+
+Add after 4.9(5):
+
+ * an aggregate of a subtype subtype; for an array aggregate, all of the
+ discrete_choices (if any) of the discrete_choice_list of each
+ array_component_association are static expressions, static ranges,
+ or static subtypes;
+
+Modify 4.9(7):
+
+ * an attribute_reference that denotes a scalar value, and whose prefix
+ denotes a static [scalar] subtype;
+
+Modify 4.9(9):
+
+ * a type_conversion whose subtype_mark denotes a static [scalar] subtype,
+ and whose operand is a static expression;
+
+Modify 4.9(10 & 11/4) to drop the parenthesized "(scalar or string)".
+
+Modify 4.9(20):
+
+ * a predefined concatenation operator whose result type is a {potentially
+ static}[string] type;
+
+ * {a predefined relational operator whose parameter types are all
+ potentially static non-scalar types none of which are descendants of
+ formal types;}
+
+ * a function for which the Static_Function aspect is True;
+
+Add after 4.9(23):
+
+For a subprogram_declaration or an expression_function_declaration, the
+following language-defined aspect may be specified with an
+aspect_specification (see 13.1.1):
+
+Static_Function The type of aspect Static_Function is Boolean.
+If directly specified, the aspect_definition shall be a static expression.
+If not specified (including by inheritance), the aspect is False.
+
+[Editor's note: Legality Rules for this aspect are below, after paragraph 37.
+The meaning was given in the paragraph 20.]
+
+Modify 4.9(24):
+
+A static constant is{
+ * a constant view declared by a full constant declaration
+or an object_renaming_declaration with a static nominal subtype, having a value
+defined by a static scalar expression or by a static {composite}[string]
+expression whose value has a length not exceeding the maximum length of a
+string_literal in the implementation{; or
+ * a deferred constant for which the aspect Static_Constant is True.
+
+For a deferred constant declaration, the following language-defined aspect may
+be specified with an aspect_specification (see 13.1.1):
+
+Static_Constant The type of aspect Static_Function is Boolean.
+If directly specified, the aspect_definition shall be a static expression.
+If not specified (including by inheritance), the aspect is False.
+
+[Editor's note: Legality Rules for this aspect are below, after paragraph 37.
+The meaning was given above.]
+
+Modify 4.9(26/3):
+
+A static subtype is either a static scalar subtype or a static
+{composite}[string] subtype. A static scalar subtype is an unconstrained scalar
+subtype whose type is not a descendant of a formal type, or a constrained
+scalar subtype formed by imposing a compatible static constraint on a static
+scalar subtype. A static {composite}[string] subtype is an unconstrained
+{array}[string] subtype whose index subtype and component subtype are static{
+and whose type is potentially static, [or] a constrained {array}[string] subtype
+formed by imposing a compatible static constraint on a static {array}[string]
+subtype{, or a constrained composite subtype formed by imposing a compatible
+static constraint on a potentially static record or private type, or on a
+constrained composite subtype. In any case, the subtype of a generic formal
+object of mode in out, and the result subtype of a generic formal function,
+are not static. Also, a subtype is not static if any Dynamic_Predicate
+specifications apply to it.
+
+[Editor's note: The only constraint allowed on record or private types is
+the null constraint, as we do not allow any discriminants. I think the case
+of a non-discriminated type is covered by "imposing" a null constraint on
+a potentially static record or private type. If not, we'll have to fix the
+wording.]
+
+Modify 4.9(32):
+
+A subtype is statically constrained if it is constrained, and its constraint
+is static. An object is statically constrained if its nominal subtype is
+statically constrained, or if it is a static {composite}[string] constant.
+
+Add after 4.9(37/2):
+
+If aspect Potentially_Static is True for a type, the type:
+ * shall not be an inherently limited type; and
+ [Sorry, no static tasks. ;-)]
+ * shall not have any discriminants; and
+ * shall not have any component whose nominal subtype is not a static subtype
+ Redundant[of a potentially static type]; and
+ AARM Proof: All static subtypes are of potentially static types.
+ * if the type is not an unconstrained array, shall not have a size
+ exceeding the size of a Wide_Wide_Character times maximum length of a
+ string_literal in the implementation.
+
+ AARM Discussion: We're allowing simple "tuples" to be static expressions, not
+ arbitrarily large and complex types. The size limit corresponds to the Ada 95
+ limit for strings, so we're not requiring carrying around massive values.
+
+ AARM Ramification: This size limit might appear to be a portability problem.
+ However, the string_literal limit is tied to the line length, and 2.2 requires
+ that to be at least 200 characters. Thus types less than 800 storage elements
+ in size ought to be portably static. [We could have used that as an
+ alternative way of saying this, if we wanted even more portability.]
+
+If aspect Static_Function is True for a subprogram_declaration S, the
+subprogram shall have a completion that is a static function, and
+that completion shall be in the same declaration list as S, or in the
+private part of package P if S is in the visible part of P.
+
+ AARM Ramification: This is necessarily an expression function. It
+ has to be available to the compiler to evaluate, thus the completion
+ has to be in the same compilation unit as the declaration.
+
+A *potentially static expression* is defined in the same way as a
+static expression except that
+ * a name denoting a formal parameter of an expression function
+ is a potentially static expression; and
+
+ * each use of "static expression" in
+ the definition of "static expression" is replaced with
+ a corresponding use of "potentially static expression"
+ in the definition of "potentially static expression".
+
+ AARM Discussion: These uses occur in the definition of "static expression"
+ in the cases of function calls, type conversions,
+ qualified expressions, membership tests, short circuit control forms,
+ conditional expressions, and parenthesized expressions.
+
+[This wording was borrowed from AI12-0075-1. Send all brickbats to the author
+of that AI. :-)]
+
+If aspect Static_Function is True for an expression_function_declaration F, then
+ * the return expression of F shall be a potentially static expression; and
+ * the return expression of F shall not contain a call to itself; and
+ * each of the parameters of F (if any) shall be of mode IN and have a
+ static subtype; and
+ * the result subtype of F shall be is a static subtype; and
+ * no precondition or postcondition expression shall applies to F.
+
+[The list of rules was borrowed from AI12-0075-1, but the wording was
+improved.]
+
+If aspect Static_Constant is True for a deferred constant declaration, the
+full declaration shall be a static constant.
+
+-----------------------
+Now, using the above, make Address potentially-static and make To_Address
+a static function:
+
+Modify 13.7(12):
+
+ type Address is implementation-defined{
+ with Potentially_Static => True};
+ Null_Address : constant Address{
+ with Static_Constant => True};
+
+Add "Static_Function" to each function of 13.7(14/3).
+
+Modify 13.7.1(10/3):
+
+ type Integer_Address is implementation-defined;
+ function To_Address(Value : Integer_Address) return Address
+ with Static_Function, Convention => Intrinsic;
+ function To_Integer(Value : Address) return Integer_Address
+ with Static_Function, Convention => Intrinsic;
+
!discussion
+
+We could just apply another hack to fix this problem directly, adding some
+rules that make type Address potentially static (which is weird as it is a
+private type). But we've done that before (see static strings) and it's
+time to at least explore a more general solution.
+
+We've had a number of issues over the years that relate to the fact that
+composite types (other that string types) are not static. For instance,
+one cannot use Composite'Size in a representation aspect as it is not static.
+
+This problem is just another example of that.
+
+The special case for string types is somewhat of a wart, because users cannot
+create similar types and functions on their own. Why should strings be static,
+but Points (pairs of integer cooredinates) or complex values (pairs of float
+values) not be static? Allowing them to be static would expand the capabilities
+of Pure and Preelaborated packages, as well as allowing their representation
+attributes to be used in representation clauses.
+
+Therefore, we define a pair of aspects that allow staticness to be extended
+to composite types and operations that are sufficiently simple. We're trying
+to allow simple "tuples" and private types thereof to be static expressions;
+we're not trying to allow everything.
+
+---------------
+
+In wording through the wording, it is obvious that a number of capabilities
+are not currently provided for static strings: relational operators, type
+conversions, and aggregates. All of these seem necessary for more generalized
+static types. We need aggregates to construct values for types like Size and
+Complex. It would be bizarre to not allow static equality tests on such types,
+as they are needed to make conditional expressions statically unevaluated
+(which is needed to work around compatibility issues, see below). Type
+conversions aren't necessary, but seem like a wart.
+
+---------------
+
+We banned discriminants as we don't need them for any comtemplated use.
+Handling discriminant constraints and the like complicates the model, even if
+we don't allow any discriminant-dependent components. Similarly, not having
+any discriminant-dependent components simplifies the model by ensuring that
+all components are present in every value.
+
+These restrictions could be lifted with some additional wording, if desired.
+
+---------------
+
+An alternative model would be that the aspects are only needed on private
+types and subprogram declarations; array and record types, and expression
+functions with the appropriate properties would automatically be potentially
+static. We did not use that model for compatibility reasons: bad static
+expressions are illegal, while the same expression in existing Ada is legal
+but raises an exception at runtime.
+
+Thus, automatically making types and functions static would introduce errors
+in cases where the code is currently legal. If that code happens to be in
+a dead branch that is never executed, there could be a significant impact.
+
+For example:
+
+ type Size is
+ Width, Height : Natural;
+ end record;
+
+ procedure Bar is
+ MY_Size : constant Size := (Width => 10, Height => 0);
+ Needed_Area : constant Natural := 100; -- Need 100 pixels.
+
+ function Area (A_Size : in Size) return Natural is
+ (A_Size.Width * A_Size.Height);
+
+ begin
+ if Area (My_Size) > 0 then
+ Put_Line ("Ratio =" &
+ Float'Image(Float (Needed_Area) / Area(My_Size))); -- (!!)
+ end if;
+ end Bar;
+
+If Size was automatically potentially static, then the divide is
+illegal (as it divides by statically by zero), even though it can never be
+executed.
-** TBD.
+Any of the Legality Rules 4.9(33-37) can cause this effect, as well as case
+statement or aggregate completeness checks.
!ASIS
Questions? Ask the ACAA Technical Agent