CVS difference for ai05s/ai05-0144-2.txt
--- ai05s/ai05-0144-2.txt 2009/10/30 04:21:42 1.1
+++ ai05s/ai05-0144-2.txt 2009/10/30 05:50:04 1.2
@@ -42,7 +42,7 @@
* N1 statically denotes a part of a stand-alone object or parameter, and
N2 statically denotes the same part of the same stand-alone object or
- [We're assuming that the first bullet covers selected_components, as
+ [We're assuming that this bullet covers selected_components, as
those are always known at compile-time - ED]
* N1 is a dereference (implicit or explicit) of P1, N2 is a dereference
@@ -55,9 +55,9 @@
static expressions with the same value, or I1 and I2 are names that
are known to denote the same object; or
- * N1 is a slice P1(R1), N2 is a slice P2(R2), the prefixes P1 and P2 are
- known to denote the same object, and the subtypes denoted by the
- ranges R1 and R2 statically match.
+ * N1 is a slice P1(S1), N2 is a slice P2(S2), the prefixes P1 and P2 are
+ known to denote the same object, and the subtypes denoted by S1 and S2
+ statically match.
AARM Discussion: This is determined statically. If the name contains
some dynamic portion other than a dereference, indexed_component, or
@@ -77,70 +77,81 @@
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, then
+A type is *known to be passed by reference* if it is tagged or
+immutably limited (see 7.5).
+AARM Reason: The by-reference property breaks privacy by requiring information
+about the full definition of partial views; these properties do not depend
+on the full definition of partial views.
+If a call C has two or more parameters of mode in out or out that
+are of a type that is not known to be passed by reference, then
the call is legal only if:
- * For each name N of an elementary type that is passed as a parameter of
+ * For each name N of an that is passed as a parameter of
mode in out or out to the call C, there is no other name among the
- other parameters of mode in out or out to C that is known to denote the
+ other parameters of mode in out or out to C that is known to refer to
+[Editor's note: see the discussion item about compatibility. Also note
+that I changed "denote the same object" to "refer to the same object",
+because this now includes composite types and thus we need the more
+complex matching included in "refer".]
If a construct C has two or more direct constituents that are names or
expressions whose evaluation may occur in an arbitrary order, at least
-one of which contains a function call with an in out, out, or
-access-to-variable parameter, then the construct is legal only if:
+one of which contains a function call with an in out or out parameter,
+then the construct is legal only if:
* For each name N that is passed as a parameter of mode in out or out
to some inner function call C2 (not including the construct C
itself), there is no other name anywhere within a direct constituent
of the construct C other than the one containing C2, that is known
- to refer to the same object; and
+ to refer to the same object.
- * For each name N'Access or N'Unchecked_Access that is passed as an
- access-to-variable parameter to some inner function call C2 (not
- including the construct C itself), there is no other name anywhere
- within a direct constitutent of the construct C other than the one
- containing C2, that is known to refer to the same object as N.
-For the purposes of checking this rule on an array aggreagate, an
-expression associated with a discrete_choice_list that has two or more
-discrete choices, or that has a nonstatic range, is considered as two or more
-separate occurrences of the expression. Similarly for a record aggregate,
-the expression of a record_component_association is considered to occur
-once for each associated component.
+For the purposes of checking this rule:
+ * For an array aggregate, an expression associated with a discrete_choice_list that
+ has two or more discrete choices, or that has a nonstatic range, is considered
+ as two or more separate occurrences of the expression;
+ * For a record aggregate:
+ - The expression of a record_component_association is considered to occur
+ once for each associated component; and
+ - The default_expression for each record_component_association with <> for which
+ the associated component has a default_expression is considered part of the
+ * For a call, any default_expression evaluated as part of the call is considered
+ part of the call.
+AARM Ramification: We do not check expressions that are evaluated only because
+of a component initialized by default in an aggregate (via <>).
+[Editor's note: I'm a bit dubious about these default_expression rules. These
+expressions are not visible to the programmer and may not actually modifiable
+by them. OTOH, it isn't very likely that they would cause a problem. These
+additional rules were suggested by the minutes of the Brest meeting, so
+they were added here.]
-AARM Reason: This prevents obvious cases of dependence on the order of
+AARM Reason: These rules prevent obvious cases of dependence on the order of
evaluation of names or expressions. Such dependence is usually a bug, and
in any case, is not portable to another implementation (or even another
-The third bullet does not check for uses of the prefix, since the access type
-and the designated object are not the same, and "known to denote the same
-prefix" does not include dereferences anyway.
-Note that these rules as a group make a symmetrical set of rules, in that either
-name can designate an object that is the prefix of the other. If the name N is
-a prefix of some other name in the call, these rules will trigger because that
-prefix would necessarily be known to designate the same object. (Nothing in these
-rules require the full other name to match; any part can match.) OTOH, we need
-explicit wording if some prefix of N matches some other name in the call.
-These rules do not require checks for most in out parameters in the top-level
-call C, as the rules about evaluation of calls prevent problems. Similarly,
-we do not need checks for short circuit operations. The rules about arbitrary
+In the case that the top-level construct C is a call, these rules do not require
+checks for most in out parameters, as the rules about evaluation of calls prevent
+problems. Similarly, we do not need checks for short circuit operations or other
+operations with a defined order of evaluation. The rules about arbitrary
order (see 1.1.4) allow evaluating parameters and writing parameters back in
an arbitrary order, but not interleaving of evaluating parameters of one call
with writing parameters back from another - that would not correspond to any
allowed sequential order.
End AARM Reason.
-AARM Ramification: Note that the latter two bullets cannot fail for a procedure or entry
-call alone; there must be at least one function with an access, in out, or out
+AARM Ramification: Note that the latter requirement cannot fail for a procedure or
+entry call alone; there must be at least one function with an in out or out
parameter called as part of a parameter expression of the call in order for it
In order to discuss this topic, we need to look at some examples.
@@ -348,7 +359,8 @@
(5) It probably doesn't pay to try to check access values, as they are rarely
analyzable, they're effectively reference parameters (which usually are
- well-defined) and users expect them to be aliased.
+ well-defined) and users expect them to be aliased. In addition, checking
+ access parameters would be incompatible.
@@ -358,6 +370,59 @@
be illegal for generic formal types; the only time things would be legal if if
the instance has the "right" actuals (but that's irrelevant since the generic is
+The rule about multiple in out parameters in a single call is incompatible,
+but virtually all programs that would be made illegal would be very dubious. For
+ procedure Do_It (Double, Triple : in out Natural) is
+ Double := Double * 2;
+ Triple := Triple * 3;
+ end Do_It;
+ Var : Natural := 2;
+ Do_It (Var, Var); -- Illegal by new rules.
+Since whether Var contains 4 or 6 after the call to Do_It depends on the compiler
+version, optimization settings, and potentially the phase of the moon, depending
+on code like this is just a ticking time bomb. So this check will mostly detect
+[Editor's note: The expansion of this rule to everything that is not required to
+be passed by-reference will also expand the incompatibility to some cases where
+there is no actual problem - such as large untagged record types, which probably
+are passed by reference by all compilers but are not required to be passed that
+way. Thus the rule we have adopted seems to violate the principle of not rejecting
+safe things. Admittedly, Erhard does not share my feeling that by-reference
+parameters is safe (even though the language semantics is well-defined and all such
+uses are portable). I fear that Erhard's insistence on expanding this applicability
+will eventually cause the entire rule to be dropped -- which would be a massive
+The decision to exclude anonymous access parameters from this cheecking means that
+most of the initial examples in fact are still legal (even if insidious). For instance,
+the Ada 95 example from above:
+ if F4(A1) = F3(F1(A1)) then
+is not detected by the proposed rules.
+This is mainly for compatibility reasons: since Ada 95 code could contain these
+sorts of problems, we don't want to make a lot of it illegal (even if it is
+dangerous). The main argument used is that functions with access parameters are
+common (as that was the workaround to not having "in out" parameters).
+It is annoying that the existence of that workaround is being used to make it harder
+to convert to "in out" parameters in those functions (as the result might be
+illegal while the original code was not -- even though both are equally dubious),
+but that cannot be helped.
+[Editor's note: I'm still dubious about this decision, especially as we seem
+willing to take the incompatibility for the multiple parameter case.]
Questions? Ask the ACAA Technical Agent