Version 1.2 of ais/ai-00392.txt
!standard 04.06(12) 04-12-07 AI95-00392/01
!standard 04.06(39)
!standard 04.06(24)
!class amendment 04-12-07
!comment This is in the Amendment (AARM), but not yet approved.
!status Amendment 200Y 04-12-07
!status work item 04-12-07
!status received 04-12-07
!priority High
!difficulty Medium
!subject Prohibit unsafe array type conversions
!summary
The addition of anonymous access types as component types (AI-230) appears
to have opened a hole through which array type conversions can be used to
create dangling references.
As with other similar constructs, this hole is plugged using a
combination of legality rules and runtime accessibility checking.
!question
Given two array types, one declared in a more nested scope than the other
and with statically matching anonymous access element types, conversion of a
value of the inner type to the outer type could result in dangling references.
Was this intended? (No.)
!proposal
As with other similar constructs (e.g., the Access attribute or conversion
between access types), a combination of legality rules and runtime
accessibility checks is used to prevent the creation of dangling references.
!wording
(This wording assumes that AI-230 is adopted.)
Add after 4.6(12)
If the component types are anonymous access types, then the
accessibility level of the operand type shall not be statically deeper
than that of the target type; and
Add after 4.6(39)
If the component types of the array types are anonymous access types,
then a check is made that the accessibility level of the operand type
is not deeper than that of the target type.
!example
procedure Static_Case is
type Less_Nested is array (Positive range <>) of access Integer;
X : Less_Nested (1 .. 10);
procedure Nested is
Local : aliased Integer := 0;
type More_Nested is array (Positive range <>) of access Integer;
Y : More_Nested := (others => Local'access);
begin
X := Less_Nested (Y); --
end Nested;
begin
Nested;
X (1).all := X(1).all + 1;
end Static_Case;
procedure Dynamic_Case is
type Less_Nested is array (Positive range <>) of access Integer;
X : Less_Nested (1 .. 10);
generic
package G is
end G;
package body G is
Local : aliased Integer := 0;
type More_Nested is array (Positive range <>) of access Integer;
Y : More_Nested := (others => Local'access);
begin
X := Less_Nested (Y); --
end Nested;
procedure Nested is
package I is new G;
begin
null;
end Nested;
begin
Nested;
X (1).all := X(1).all + 1;
end Dynamic_Case;
!corrigendum 4.6(12)
Replace the paragraph:
- The component subtypes shall statically match; and
by:
- The component subtypes shall statically match;
- If the component types are anonymous access types, then the
accessibility level of the operand type shall not be statically deeper
than that of the target type; and
!corrigendum 4.6(24)
!comment dummy change to force a conflict.
@drepl
In a view conversion for an untagged type, the target type shall be convertible
(back) to the operand type.
@dby
In a view conversion for an untagged type, the target type shall be convertible
(back) to the operand type.
!corrigendum 4.6(39)
Insert after the paragraph:
- In either array case, the value of each component of the result is
that of the matching component of the operand value (see 4.5.2).
the new paragraph:
- If the component types of the array types are anonymous access types,
then a check is made that the accessibility level of the operand type
is not deeper than that of the target type.
!ACATS test
An ACATS B and C test need to be constructed to check these rules.
!appendix
Questions? Ask the ACAA Technical Agent