AI22-0142-1
!standard 3.10.2(27.1/2) 26-04-30 AI22-0142-1/05
!standard 4.9.1(1.3/2)
!standard 4.9.1(3)
!class Amendment
!status Revision-202Y 25-10-08
!status ARG Approved 11-0-2 25-10-08
!status work item 25-09-23
!status received 25-09-23
!assigned author Tucker Taft
!submitter Tucker Taft
!priority Low
!difficulty Medium
!subject Relax matching index constraint rules
We relax the rules for statically matching index constraints to allow defining an access type to point to a discriminant-dependent (aliased) array component.
RM 3.10.1(27.1/2) requires statically-matching subtypes when using the 'Access attribute to create a pointer to an object. This can be nearly impossible when the target is discriminant-dependent, as in the following scenario:
type Text (L : Natural) is record
Chars : aliased String (1..L);
end record;
procedure Fun (X : in out Text) is
type Chars_Ptr is access all String (X.Chars'Range)
with Convention => C;
procedure C_Proc (CP : Chars_Ptr; Len : Interfaces.C.int)
with Import, Convention => C;
begin
C_Proc (X.Chars'Access, X.Chars'Length); -- Currently illegal
end Fun;
Clearly Chars_Ptr has a dynamic designated subtype, and the statically matching rule for dynamic constraints (4.9.1(1.3/2)) is that they must have originated from the same elaboration of a subtype indication. But in this case, the definition of Chars_Ptr is a separate elaboration, even though it is simply carrying over the 'Range from some other subtype of String.
Should the designated subtype of Chars_Ptr be considered to statically match the subtype of X.Chars? (Yes.)
The rules for statically matching index constraints should be relaxed just a bit, to allow for the case where we define one array subtype using the 'Range attribute(s) of some other array object or subtype of the same type.
Add after 4.9.1(1.3/2):
Modify 4.9.1(3):
Two ranges of the same type statically match if both result from the same evaluation of a range, {if one is the range constraint of an object for which renaming is allowed (see 8.5.1), or of a subtype, and the other is defined by a Range attribute reference where the prefix statically names the object or subtype, }or if both are static and have equal corresponding bounds.
AARM Ramification: An X'Range attribute reference in this context may be replaced by X'First .. X'Last, due to the equivalence given in 3.6.2.
This issue arose from customer code trying to prove correctness of passing an array to a C routine. The static matching requirement can help with safety, but if it is too restrictive then it becomes less useful. Allowing index constraints to match statically if all of their discrete ranges match statically seems eminently safe. Similarly, it seems safe to allow ranges to match statically if one is defined by attribute references whose prefixes statically name the other.
There is a question of whether it will be an implementation burden to allow a value of an access-to-dynamically-constrained array type to point at a discriminant-dependent component. Presumably by marking it as "aliased" the implementation can ensure that this is feasible, since that would be the main reason for marking such a component as aliased.
@drepl
@xbullet{both are nonstatic and result from the same elaboration of a @fa{constraint} of a @fa{subtype_indication} or the same evaluation of a @fa{range} of a @fa{discrete_subtype_definition}; or}
@dby
@xbullet{both are nonstatic and result from the same elaboration of a @fa{constraint} of a @fa{subtype_indication} or the same evaluation of a @fa{range} of a @fa{discrete_subtype_definition};}
@xbullet{both are nonstatic index constraints and the corresponding discrete ranges statically match; or}
@drepl
Two ranges of the same type @i{statically match} if both result from the same evaluation of a @fa{range}, or if both are static and have equal corresponding bounds.
@dby
Two ranges of the same type @i{statically match} if both result from the same evaluation of a @fa{range}, if one is the range constraint of an object for which renaming is allowed (see @ref{8.5.1}), or of a subtype, and the other is defined by a Range attribute reference where the prefix statically names the object or subtype, or if both are static and have equal corresponding bounds.
The example given in the !issue would become legal with this change.
This would be a simple C test, which might be based on an existing B test that would have failed without this change.