CVS difference for ai12s/ai12-0027-1.txt

Differences between 1.4 and version 1.5
Log of other versions for file ai12s/ai12-0027-1.txt

--- ai12s/ai12-0027-1.txt	2012/07/17 23:29:48	1.4
+++ ai12s/ai12-0027-1.txt	2012/12/01 04:21:12	1.5
@@ -1,95 +1,177 @@
-!standard 4.6(8/2)                                   12-07-15    AI12-0027-1/02
+!standard 4.6(8/2)                                   12-11-30    AI12-0027-1/03
 !standard 4.6(24.8/2)
 !class binding interpretation 12-06-04
 !status work item 12-06-04
 !status received 12-04-09
-!priority Low
+!priority Medium
 !difficulty Medium
-!subject Contract violation for aliased components of actuals for formal array types
-!summary 
+!subject Access values should never designated unaliased components
+!summary
 
-An additional "assume-the-worst" Legality Rule is adopted to avoid the problem noted
-in the question.
+** TBD
 
 !question
 
-Type conversions from array types with unaliased components to array types with
-aliased components (4.6(24.8)) are prohibited, in order to prevent the discriminant of an
-aliased discriminated component from being modified. 4.6(8) says that for a
-view conversion used as an OUT or IN OUT actual parameter, the types have to be
-convertible both ways, which means that an array type with aliased components
-can't be converted to an array type with unaliased components either.
+We don't want access values pointing to unaliased objects.
 
-However, it seems that you can get around this by using generics, since by
-12.5.3(8) and AARM 12.5.3(8.a) it's OK if a formal array type's components are
-unaliased and the actual's are aliased, and Legality Rules such as 4.6(24.8)
-aren't checked in an instance body.
+But there appear to be several ways to create such values.
+
+4.6(24.8) prohibits view conversions from array types with unaliased components to array types with
+aliased components. However, value conversions can also create such components.
+Consider:
+
+    type T is tagged null record;
+
+    type Rec is record F1 : T; F2 : Integer; end record;
+
+    type Rec_Ref is access constant Rec;
+    Ptr : Rec_Ref;
+
+    subtype Index is Integer range 1 .. 3;
+
+    type A1 is array (Index) of Rec;
+    type A2 is array (Index) of aliased Rec;
 
-This creates a hole which should be fixed, right? (Yes.)
+    X1 : A1;
+  begin
+    Ptr := A2 (X1)(Index'First)'Access;
+    -- Ptr now designates an unaliased object
 
+In addition, the existing wording doesn't deal with contract model issues with
+generics. By 12.5.3(8) and AARM 12.5.3(8.a) it's OK if a formal array type's
+components are unaliased and the actual's are aliased, and Legality Rules such
+as 4.6(24.8) aren't checked in an instance body.
+
 !recommendation
 
 (See summary.)
 
 !wording
+
+This wording has two alternatives; the first alternative solves the problem
+statically, the second dynamically.
+
+Wording common to both alternatives (the first alternative solves the problem statically, the second dynamically):
+
+append to the end of the Legality Rules section of 4.6 (after 24.p/2):
+   In addition to the places where Legality Rules normally apply (see 12.3),
+   these rules apply also in the private part of an instance of a generic unit.
+
+Wording alternative #1: (disallow the problematic construct)
+
+replace 4.6(24.8/2)
+
+   If the target type of a view conversion has aliased components, then so
+   shall the operand type; and
+
+with
+
+   It is said that the conversion *may yield aliased components* if
+     - the target type has aliased components; or
+     - the target type is generic formal array type and the
+       conversion occurs within the body of G or within the
+       body of a generic unit declared within the declarative
+       region of G.
+
+TBD: this is the 4th occurrence of this somewhat opaque "within the body of a
+      of a generic unit declared within" wording. See 8.5.1, 8.5.4, and 12.6.
+      Do we want to define a term like "the unverified region" of
+      a generic  unit and then use that term in these 4 places?
+
+   If the conversion may yield aliased components and the operand type
+   does not have aliased components, then
+     - the conversion shall not be a view conversion; and
+     - the target type shall not be a by-reference type; and
+     - the target type shall not have private part.
+
+TBD: This wording could be restructured to avoid defining a term
+      which is only used once, but then we get into either nested
+      ifs or mixing of conjunctions and disjunctions (which requires
+      nested lists).
 
-append to 4.6(8/2):
-   In addition to the places where Legality Rules normally apply
-   (see 12.3), this rule applies also in the private part of an
-   instance of a generic unit.
-
-TBD: do we need similar boilerplate for 21/3 and 24/3? Let's wait
-     until a need is demonstrated.
-
-append after 4.6(24.8/2), as another bulleted list item:
-
-   - if the Target_Type of a view conversion is a generic formal array
-     type of a generic unit G that does not have aliased components, then
-     the conversion shall not occur within the body of G, nor within the
-     body of a generic unit declared within the declarative region of G.
-
-TBD: this is the 4th occurrence of this somewhat opaque "within the
-      body of a of a generic unit declared within" wording. See 8.5.1,
-      8.5.4, and 12.6. Do we want to define a term like "the extended
-      body" of a generic unit and then use that term in these 4 places?
+AARM note:
+    The "shall not have a private part" clause is needed
+    because otherwise the preceding "by-reference type" rule
+    would break privacy.
 
+========================
+
+Wording alternative #2: (allow the problematic construct)
+
+Append at the end of Dynamic Semantics section of 4.6:
+
+    Evaluation of a value conversion of a composite type may, in some cases,
+    create a new anonymous object [, similar to the object created by the
+    evaluation of an aggregate or a function call]. In other cases,
+    evaluation of a value conversion may yield only a new view of the
+    operand object, and no new object is created. The circumstances under
+    which creation of a new object is required, permitted, or prohibited
+    are as follows:
+
+      - If there is a composite type that is an ancestor of both the target
+        type and then either
+           - the target type is a by-reference type; or
+           - all type-related representation aspects of the target and
+             operand types agree and the alignment aspects of the
+             first named subtypes of the two types agree
+        then creation of a new object is prohibited.
+
+   TBD: Do we want to prohibit copying if alignment of operand type is
+        an unequal multiple of the alignment of the target type?
+
+      - Otherwise, if there is no type that is an ancestor of both the target
+        type and the operand type, and if the target type is an array type
+        having aliased components, and if the operand type is not such an
+        array type, then creation of a new object is required.
+
+   AARM note:
+   This rule is needed to prevent creation of an aliased view of an
+   unaliased array element.
+
+      - Otherwise, creation of a new object is permitted. [It is expected
+        that a new object will be created if the two types have incompatible
+        representations, but that is not required by this rule.]
+
+   If a new object is created, then the initialization of that object is
+   an assignment operation.
+
+   AARM note: This makes a difference in the case of converting from
+   an array type with unaliased components to one with aliased components
+   if the element type has a controlled part.
+
+
+Append after 3.10.2(10/3):
+
+   The accessibility of a value conversion (see 4.6) is defined as for an
+   aggregate.
+
+In 6.2(10/3), replace
+
+   For a parenthesized expression, qualified_expression, or type_conversion,
+   this object is the one associated with the operand.
+
+with
+
+   For a parenthesized expression, qualified_expression, or view conversion,
+   this object is the one associated with the operand.
+   For a value conversion, the associated object is the anonymous result
+   object if such an object is created (see 4.6); otherwise it is the
+   associated object of the operand.
+
 !discussion
+
+[Editor's musings without understanding the above very well:
 
-There seem to be four possibilities, none of which seem very good:
+The statically checked rule almost certainly is incompatible in some cases.
+We need to develop some examples to see how severe this might be.
 
-(1) Modify the matching rule to require that the aliased (or not) state of
-the components match exactly. This is probably what the rule ought to have
-been, but it is incompatible. Moreover, such a rule would require having
-an extra version of generic sort routines and the like just to support
-the possibility that the components are aliased. Bleech!!
-
-(2) Use an assume-the-worst rule in generic bodies for the problematic type
-conversions. That is, array type conversions would essentially be banned for
-types derived from generic formal types unless the formal type had aliased
-components. This seems pretty draconian.
-
-(3) Use the old "raise Program_Error for a contract violation" trick. That is,
-have a array type conversion raise Program_Error if the target components are
-aliased and the source components are not (or vice-versa). This would work
-but would provide a "tripping hazard" that could easily be missed in testing
-of a reusable component (the component would only fail with specific parameter
-types).
-
-(4) Determine if we really need the rule at all, as the original reason was
-to prevent the changing of a discriminant of an aliased component (something
-we no longer try to prohibit in general, because there always were holes
-in the rules). So perhaps we don't need the strong conversion rule. But this
-seems like a large can of worms to open up.
-
-We chose (2), as this avoids any run-time overhead. Any such type conversions
-could be moved to the specification as a workaround, using a helper "expression
-function". (3) would require run-time overhead for this rare case (although it
-would be limited to the case itself unless generic code sharing is used by
-the implementation). (1) would prevent the use of Ada.Containers.Generic_Array_Sort
-with arrays of aliased components, which seems insane given that procedure
-probably doesn't use any problematic type conversions.
-(4) just seems too dangerous (and eliminating the type conversion rule was
-considered and rejected for Ada 2005, so it seems likely that it is still need).
+The dynamically checked rule doesn't have an inconsistency (runtime
+incompatibility) unless something nasty is happening. But of course there is a
+runtime overhead in some cases.
+
+Note that the "dynamic" wording defines the accessibility level of a value
+conversion; this might cause some incompatibility (as it might cause
+accessibility checks to fail that currently succeed).
 
 !ACATS test
 
@@ -175,5 +257,19 @@
 12.5.3(8) and AARM 12.5.3(8.a) it's OK if a formal array type's components are
 unaliased and the actual's are aliased, and Legality Rules such as 4.6(24.8)
 aren't checked in an instance body.
+
+****************************************************************
+
+[*** Editor's note: There are 33 unfiled ARG e-mails that should be here.]
+
+****************************************************************
+
+From: Steve Baird
+Sent: Friday, November 30, 2012  7:07 PM
+
+> Thanks to Randy for much useful discussion on this one.
+
+[Followed by new !wording and !discussion sections, in version /03 of the AI;
+most of the submitted !discussion was placed in the !question.]
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent