CVS difference for ai05s/ai05-0144-2.txt

Differences between 1.9 and version 1.10
Log of other versions for file ai05s/ai05-0144-2.txt

--- ai05s/ai05-0144-2.txt	2010/05/20 05:09:01	1.9
+++ ai05s/ai05-0144-2.txt	2010/06/03 06:11:02	1.10
@@ -1,6 +1,8 @@
-!standard 6.02 (11)                                 10-05-03  AI05-0144-2/06
+!standard 6.04.01 (6)                                 10-06-02  AI05-0144-2/07
+!standard 6.0.5(5.8/3)
 !class Amendment 09-06-07
 !status Amendment 2012 10-04-23
+!status work item 10-05-20
 !status ARG Approved  5-0-4  10-02-26
 !status work item 09-06-07
 !status received 09-06-07
@@ -36,7 +38,7 @@
 
 !wording
 
-Add after 6.2(11):
+Add after 6.4.1(6):
 
 Two names are *known to denote the same object* if:
 
@@ -47,32 +49,14 @@
     denote the same object, and their selector_names denote the
     same component; or
 
-  * both names are dereferences (implicit or explicit), the
-    dereferenced names are known to denote the same object,
-    and both names have the same immediately enclosing complete context (see
-    8.6); or
+  * both names are dereferences (implicit or explicit) and the
+    dereferenced names are known to denote the same object; or
 
-AARM Reason: We need the requirement to have the same enclosing complete context
-in order to avoid problems with renames. Consider:
-
-      type Ref is access Some_Type;
-      Ptr : Ref := new Some_Type'(...);
-      X : Some_Type renames Ptr.all;
-   begin
-      Ptr := new Some_Type'(...);
-      P (Func_With_Out_Params (Ptr.all, X));
-
-X and Ptr.all should not be known to denote the same object, since they denote different
-allocated objects.
-End AARM Reason.
-
   * both names are indexed_components, their prefixes are known
     to denote the same object, and each of the pairs of corresponding
-    index values are known to have the same value; or
-
-AARM Discussion: "Statically known to have the same value" is defined below.
-The term is necessary to avoid problems with renames similar to the dereference
-example above.
+    index values are either both static expressions with the same
+    static value or both names which are known to denote the
+    same object; or
 
   * both names are slices, their prefixes are known to denote the
     same object, and the two slices have statically matching
@@ -80,25 +64,35 @@
 
   * one of the two names statically denotes a renaming declaration
     whose renamed object_name is known to denote the same object
-    as the other name.
+    as the other, and every index expression for each
+    indexed_component which occurs within the renamed
+    object_name is a known to be unvarying expression, and the dereferenced
+    name for each (implicit or explicit) dereference which
+    occurs within the renamed object_name is a known to be unvarying name.
 
 AARM Reason: This exposes known renamings of slices, indexing, and so on
 to this definition. In particular, if we have
    C : Character renames S(1);
 then C and S(1) are known to denote the same object.
-End AARM Reason.
+
+We need the requirement for dereferences and index expressions to be
+"known to be unvarying" in renames in order to avoid problems from later changes
+to those parts of renamed names. Consider:
+
+      type Ref is access Some_Type;
+      Ptr : Ref := new Some_Type'(...);
+      X : Some_Type renames Ptr.all;
+   begin
+      Ptr := new Some_Type'(...);
+      P (Func_With_Out_Params (Ptr.all), X);
 
-AARM Ramification: "Known to denote the same object" is intended to be an equivalence
-relationship, that is, it is reflexive, symmetric, and transitive. We believe this
-follows for the rules. For instance, given the following declarations:
-     S   : String(1..10);
-     ONE : constant Natural := 1;
-     R   : Character renames S(1);
-the names R and S(1) are known to denote the same object by the sixth bullet, and
-S(1) and S(ONE) are known to denote the same object by the fourth bullet, so using
-the sixth bullet on R and S(ONE), we simply have to test S(1) vs. S(ONE), which
-we already know denote the same object.
-END AARM Ramification.
+X and Ptr.all should not be known to denote the same object, since they denote
+different allocated objects (and this is not an unreasonable thing to do).
+
+We don't need a similar requirement for slices as the existing requirement for
+statically matching index constraints eliminates any problems (the index
+constraints either have to be static or declared by the same subtype declaration).
+End AARM Reason.
 
 
     AARM Discussion: Whether or not names or prefixes are known to denote the
@@ -113,55 +107,71 @@
     rules are intended to be conservative.
     End AARM Discussion.
 
-Given two names or expressions of the same discrete type, one is
-*known to have the same value* as the other if
+    AARM Ramification: "Known to denote the same object" is intended to be an equivalence
+    relationship, that is, it is reflexive, symmetric, and transitive. We believe this
+    follows from the rules. For instance, given the following declarations:
+        S   : String(1..10);
+        ONE : constant Natural := 1;
+        R   : Character renames S(1);
+    the names R and S(1) are known to denote the same object by the sixth bullet, and
+    S(1) and S(ONE) are known to denote the same object by the fourth bullet, so using
+    the sixth bullet on R and S(ONE), we simply have to test S(1) vs. S(ONE), which
+    we already know denote the same object.
+    END AARM Ramification.
 
-  * both are static expressions and their values are the same; or
 
-  * both are names and the two names are known to denote the same object and
-    that object is a constant object; or
 
-AARM discussion: A dereference of an access-to-constant value denotes a constant
-view of a potentially variable object, not a constant object.
-
-  * both are names and the two names are known to denote the same object and
-    both names have the same immediately enclosing complete context (see 8.6);
-    or
-
-  * one of the two is a name which statically denotes a renaming declaration
-    whose renamed object_name is known to have the same value as the other
-    name or expression; or
-
-  * one of the two is a name which statically denotes a non-deferred constant
-    object whose initialization expression is known to have the same
-    value as the other name or expression; or
-
-  * one of the two is a parenthesized expression or qualified_expression
-    whose operand is known to have the same value as the other name
-    or expression.
-
-AARM Discussion: This is a slippery slope in that we could continue to add
-rules here until the cows come home [thanks to the Beatles for that phrase].
-For instance, we could imagine having "Both expressions are calls to the same
-predefined operator, and the corresponding operands of the expressions are
-statically known to have the same value." But the above captures all of the
-most likely cases.
-
-AARM To Be Honest: "Known to have the same value" doesn't guarantee
-that the value is the same in some obscure cases:
-* An intervening function call changes the value of an object included in one
-of the expressions;
-* One of the expressions includes a Volatile variable modified outside of the
-program;
-* One of the expressions includes a variable defined with an address clause
-(or similar features) and an intervening subprogram call modifies its location.
-These aren't a problem for this use; the first case is exactly what we are
-trying to detect (code that is not portable because it depends on the order
-of evaluation), and the others are unspeakably tricky if they are actually
-intended behavior. However, future authors of the standard should take care
-if they use this term in some other context.
+A name or expression is *known to be unvarying* if it denotes:
+ * a static expression; or
+ * a constant object; or
+
+AARM Discussion: This covers constant object_declarations, generic formal *in* objects, 
+   constant extended return objects, and exception choice parameters.
+
+ * a loop parameter; or
+ * a non-aliased formal parameter of mode *in*; or
+[Editor's note: "non-aliased" assuming that AI-142-4 is approved.]
+ * a selected_component of a known to be unvarying name.
+
+AARM Ramification: Dereferences, indexed_components, and slices are never known to be
+unvarying even if the prefix is known to be unvarying. It is important that be true for
+a dereference of an access-to-constant, as such an access may designate a variable object.
+We could have included indexed_components with all index expressions being known to be
+unvarying, but it doesn't seem important for the usage and we can always add more rules
+if we are letting too many obvious cases slip through.
+
+AARM To Be Honest: The inclusion of selected components and composite *in* parameters
+means that it might be possible to alter the value of the name or expression by another
+access path. For the use that we are putting this term to, this is OK; the modification
+via another access path is very tricky and it is OK to reject code that would be buggy
+except for the tricky code. For example:
+
+     Global : Tagged_Type;
+
+     procedure Foo (Param : in Tagged_Type := Global) is
+         X : Element renames Some_Global_Array (Param.C);
+     begin
+         Global.C := Global.C + 1;
+         Swap (X, Some_Global_Array (Param.C));
+
+The rules will flag procedure Swap as illegal, since X and Some_Global_Array (Parameter.C)
+are known to denote the same object (even though they will actually represent different objects
+if Param = Global). But this is only incorrect if the parameter actually is Global and not
+some other value; the error could exist for some calls. So this flagging seems harmless.
+
+Similar examples can be constructed using stand-alone composite constants with controlled
+or immutably limited components.
 End AARM To Be Honest.
 
+[Editor's note: We used "known to be unvarying" here as terms using forms of "constant"
+seemed to be misleading ("constant" has a meaning in Ada and this is slightly different).
+For instance, the first term used was "known constant value" which was intended to be read
+"(known constant) value", but it could also be read "known (constant value)" which seems to
+imply that the value is known, not just that the value is a constant. "known constant name"
+and "known constant expression" have similar issues. And all of these engender confusion
+with the meaning of "constant" as defined in 3.3.1.]
+
+
 Two names are *known to refer to the same object* if
 
      The two names are known to denote the same object; or
@@ -181,6 +191,7 @@
     dereference changes the object in question. (There is nothing shared
     between an access value and the object it designates.)
 
+
 If a call C has two or more parameters of mode in out or out that
 are of an elementary type, then the call is legal only if:
 
@@ -242,6 +253,19 @@
 to fail.
 
 
+[Editor's note: In defining "known to be unvarying", it was noticed that the wording
+for extended_return_statements defines it to be a full constant declaration, but fails
+to define the object as a constant object. The other three cases all explicitly define
+themselves to be constant objects (that never happens by default). We correct that here.]
+
+Modify 6.5(5.8/3) as defined by AI05-0015-1:
+
+Within an extended_return_statement, the return object is declared
+with the given defining_identifier, with the nominal subtype defined
+by the return_subtype_indication. An extended_return_statement
+with the reserved word constant is a full constant declaration [for]{that declares}
+the return object{ to be a constant object}.
+
 !discussion
 
 In order to discuss this topic, we need to look at some examples.
@@ -420,10 +444,10 @@
 principles:
 
 (1) This problem is more insidious than "ordinary" side effects in functions. A
-    function a routine that uses a side-effect internally ought to have been
+    function that uses a side-effect internally ought to have been
     written so that the side-effect doesn't damage the correctness of the
     function. (Otherwise, the function could only be called once, which would be
-    unusual.) On the other hand, a side effect occurring in a call is could not
+    unusual.) On the other hand, a side effect occurring in a call could not
     be known to the author of the function and may not be known to the author of
     the call either. This is code that is clearly non-portable, and is likely to
     break on a different compiler (or different compiler version, or even
@@ -458,7 +482,7 @@
 Note that there is no generic contract issues with these rules. This is a case
 where more is allowed (strictly) in an instance when more information (such as
 about the kinds of types) is available. In the generic, all of these cases would
-be illegal for generic formal types; the only time things would be legal if if
+be illegal for generic formal types; the only time things would be legal is if
 the instance has the "right" actuals (but that's irrelevant since the generic is
 already illegal).
 
@@ -484,7 +508,7 @@
 bugs. (Checks against existing code bases showed very few instances of this
 incompatibility, and most were undetected bugs.)
 
-This rule only applies parameters that are certain to be passed by copy.
+This rule only applies to parameters that are certain to be passed by copy.
 Parameters that are passed by reference have a defined semantics and are not
 (necessarily) a problem. Since we intend to only reject known-to-be dubious
 constructs, including types that *might* be passed by copy would be going too far.
@@ -516,14 +540,12 @@
 
 (See discussion.)
 
-!corrigendum 6.2(11)
+!corrigendum 6.4.1(6)
 
 @dinsa
-For parameters of other types, it is unspecified whether the parameter is passed
-by copy or by reference.
+The type of the actual parameter associated with an access parameter
+shall be convertible (see 4.6) to its anonymous access type.
 @dinss
-@s8<@i<Legality Rules>>
-
 Two @fa<name>s are @i<known to denote the same object> if:
 
 @xbullet<both @fa<name>s statically denote the same stand-alone object
@@ -533,31 +555,45 @@
 known to denote the same object, and their @fa<selector_name>s denote the
 same component; or>
 
-@xbullet<both @fa<name>s are dereferences (implicit or explicit), the
-dereferenced @fa<name>s are known to denote the same object,
-and both @fa<name>s have the same immediately enclosing statement or
-declaration; or>
+@xbullet<both @fa<name>s are dereferences (implicit or explicit) and the
+dereferenced @fa<name>s are known to denote the same object; or>
 
 @xbullet<both @fa<name>s are @fa<indexed_component>s, their @fa<prefix>es are
 known to denote the same object, and each of the pairs of corresponding
-index values are either static expressions with the same value
-or @fa<name>s that are known to denote the same object; or>
+index values are either both static expressions with the same static value
+or both names which are known to denote the same object; or>
 
 @xbullet<both @fa<name>s are @fa<slice>s, their @fa<prefix>es are known to
 denote the same object, and the two @fa<slice>s have statically matching
-index constraints; or
+index constraints; or>
 
 @xbullet<one of the two @fa<name>s statically denotes a renaming declaration
-whose renamed @i<object_>@fa<name> is known to denote the same object
-as the other @fa<name>; or
+whose renamed @i<object_>@fa<name> is known to denote the same object as the other,
+and every index @fa<expression> for each @fa<indexed_component> which occurs
+within the renamed @i<object_>@fa<name> is a known to be unvarying @fa<expression>,
+and the dereferenced @fa<name> for each (implicit or explicit) dereference which
+occurs within the renamed @i<object_>@fa<name> is a known to be unvarying @fa<name>.>
+
+A @fa<name> or @fa<expression> is @i<known to be unvarying> if it denotes:
+@xbullet<a static @fa<expression>; or>
+@xbullet<a constant object; or>
+@xbullet<a loop parameter; or>
+@xbullet<a non-aliased formal parameter of mode @b<in>; or>
+@xbullet<a @fa<selected_component> of a known to be unvarying @fa<name>.>
+
+Two @fa<name>s are @i<known to refer to the same object> if:
+
+@xbullet<The two @fa<name>s are known to denote the same object; or>
+
+@xbullet<One of the @fa<name>s is a @fa<selected_component>, @fa<indexed_component>,
+or @fa<slice> and its @fa<prefix> is known to refer to the same object
+as the other @fa<name>; or>
+
+@xbullet<One of the two @fa<name>s statically denotes a renaming declaration
+whose renamed @i<object_>@fa<name> is known to refer to the same object
+as the other name.>
 
-@xbullet<both @fa<name>s are known to denote the same object as a third
-@fa<name>.>
 
-Two @fa<name>s are @i<known to refer to the same object> if the @fa<name>s
-are known to denote the same object, or if one of the two @fa<name>s is known to
-denote a subcomponent or slice of the object denoted by the others.
-
 If a call @i<C> has two or more parameters of mode @b<in out> or @b<out> that
 are of an elementary type, then the call is legal only if:
 
@@ -592,6 +628,22 @@
 is considered part of the @fa<aggregate>;>
 @xbullet<For a call, any @fa<default_expression> evaluated as part of the call
 is considered part of the call.>
+
+
+!corrigendum 6.5(5.7/2)
+
+@drepl
+Within an @fa<extended_return_statement>, the @i<return object> is declared
+with the given @fa<defining_identifier>, with the nominal subtype defined
+by the @fa<return_subtype_indication>.
+@dby
+Within an @fa<extended_return_statement>, the @i<return object> is declared
+with the given @fa<defining_identifier>, with the nominal subtype defined
+by the @fa<return_subtype_indication>. An @fa<extended_return_statement>
+with the reserved word @b<constant> is a full constant declaration that declares
+the return object to be a constant object.
+
+
 
 !ACATS test
 

Questions? Ask the ACAA Technical Agent