CVS difference for 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