Version 1.5 of ai12s/ai12-0027-1.txt

Unformatted version of ai12s/ai12-0027-1.txt version 1.5
Other versions for file ai12s/ai12-0027-1.txt

!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 Medium
!difficulty Medium
!subject Access values should never designated unaliased components
!summary
** TBD
!question
We don't want access values pointing to unaliased objects.
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;
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).
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:
The statically checked rule almost certainly is incompatible in some cases. We need to develop some examples to see how severe this might be.
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
An ACATS B-Test should be created to test these rules.
!appendix

!topic Aliased components: generic contract model violation?
!reference 4.6(24.8), 4.6(8), 12.5.3(8)
!from Adam Beneschan 12-04-09
!discussion

Consider:

-------------------------------------------------------------------------------

package Pack1 is
    type T (D : Integer := 0) is null record;
    type T_Arr is array (Natural range <>) of T;  -- unaliased components
    procedure Increment_Discriminant (Arr : in out T_Arr; Index : Natural);
end Pack1;

package body Pack1 is
    procedure Increment_Discriminant (Arr : in out T_Arr; Index : Natural) is
    begin
        Arr (Index) := (D => Arr (Index).D + 1);
    end Increment_Discriminant;
end Pack1;

with Pack1;
package Pack2 is
    type My_Arr is array (Natural range <>) of aliased Pack1.T;
end Pack2;

with Pack2;
package Pack3 is
    procedure Illegal (Arr : in out Pack2.My_Arr; Index : Natural);
end Pack3;

with Pack1;
package body Pack3 is
    procedure Illegal (Arr : in out Pack2.My_Arr; Index : Natural) is
    begin
        Pack1.Increment_Discriminant (Pack1.T_Arr (Arr), Index);
            -- view conversion illegal by 4.6(24.8) and 4.6(8)
    end Illegal;
end Pack3;

with Pack1;
generic
    type Formal_Arr is array (Natural range <>) of Pack1.T; package Pack4 is
    procedure Mess_With (Arr : in out Formal_Arr; Index : Natural);
end Pack4;

package body Pack4 is
    procedure Mess_With (Arr : in out Formal_Arr; Index : Natural) is
    begin
        Pack1.Increment_Discriminant (Pack1.T_Arr (Arr), Index);
    end Mess_With;
end Pack4;

with Pack2;
with Pack4;
package Pack5 is
    package New_Pack4 is new Pack4 (Pack2.My_Arr);
        -- generic contract model violation?
end Pack5;

-------------------------------------------------------------------------------

As I understand it, a rule was added in AI95-168 and AI95-363 to prohibit type
conversions from array types with unaliased components to array types with
aliased components (4.6(24.8)), 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.  This
makes the type conversion in the body of Pack3 illegal, which is the desired
behavior since otherwise the discriminant of an aliased component of My_Arr
would be modified.  Did I understand this correctly?

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.

****************************************************************

[*** 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