Version 1.1 of ai05s/ai05-0207-1.txt
!standard 6.3.1(16/2) 10-02-15 AI05-0207-1/01
!class binding interpretation 10-02-15
!status work item 10-02-15
!status received 10-01-25
!priority Low
!difficulty Easy
!qualifier Omission
!subject Access constant is considered for mode conformance
!summary
Mode conformance includes whether access parameters are access-to-constant
or access-to-variable.
!question
12.6(8) says that mode conformance is required for an instance. 6.3.1(16/2)
says that the designated types of access parameters need to staticaly match,
but there are no other requirements.
Consider:
generic
type T is private;
CONST_VAL : T;
with procedure PROC (X : access constant T); package Gen_Pack1 is
procedure Try_This;
end Gen_Pack1;
package body Gen_Pack1 is
C : aliased constant T := CONST_VAL;
procedure Try_This is
begin
PROC (C'access);
end Try_This;
end Gen_Pack1;
package Pack2 is
procedure Modify_The_Constant;
end Pack2;
with Gen_Pack1;
package body Pack2 is
type Rec is record
F1 : Integer;
end record;
procedure Bump (X : access Rec) is
begin
X.F1 := X.F1 + 1;
end Bump;
package Inst is new Gen_Pack1 (Rec, (F1 => 10), Bump);
procedure Modify_The_Constant is
begin
Inst.Try_This;
end Modify_The_Constant;
end Pack2;
One hopes that something makes this illegal!
!recommendation
(See Summary.)
!wording
Modify 6.3.1(16/2):
Two profiles are mode conformant if they are type-conformant, and corresponding
parameters have identical modes, and, for access parameters or access result
types, the designated subtypes statically match{ and either both or neither are
access-to-constant}, or the designated profiles are subtype conformant.
!discussion
We fix this problem by adjusting mode conformance to include access-to-constant
matching for access parameters and results.
The basic idea of mode conformance is that it implies that the legality checks
for a call will be the same for any conformant subprogram. (Similarly, type
conformance implies that resolution will be the same.) As such, it needs to
include whether or not a particular parameter is access-to-constant or
access-to-variable; this is the access parameter equivalent to mode "in"
versus mode "in out".
Note that this change has a small incompatibility compared to the Ada 2005 rules;
the following is now illegal:
procedure P (A : access constant T);
procedure R (A : access T) renames P; --
This seems fairly consistent with the handling of null exclusions in renaming,
so it is unlikely to be a surprise.
We considered, but rejected, adjusting the rules for generic matching only.
Ada has a design principle that generic formal subprograms work the same way
as subprogram renaming, and adopting a generic-only rule would break this
principle.
!corrigendum 6.3.1(16/2)
Replace the paragraph:
Two profiles are mode conformant if they are type-conformant, and
corresponding parameters have identical modes, and, for access parameters or
access result types, the designated subtypes statically match, or the
designated profiles are subtype conformant.
by:
Two profiles are mode conformant if they are type-conformant, and
corresponding parameters have identical modes, and, for access parameters or
access result types, the designated subtypes statically match and either both
or neither are access-to-constant, or the designated profiles are subtype
conformant.
!ACATS Test
Create a B-Test to check that the examples in the question and in the
discussion are rejected.
!appendix
!topic Conformance rules and "access constant"
!reference 4.9.1(2/2), 6.3.1(16-17), 12.6(8)
!from Adam Beneschan 10-01-25
!discussion
4.9.1(2) says that if one anonymous access type is access-constant, and the
other isn't, the subtypes don't statically match. The rules in 6.3.1(16-17) say
that static subtype matching is required for two profiles to be
subtype-conformant, but not for mode conformance. 12.6(8) says that for an
instance of a generic formal subprogram, only mode conformance is required, not
subtype conformance. (The last half of 6.3.1(16) requires that *designated*
subtypes statically match for mode conformance, but not that the access subtypes
themselves statically match.)
So what makes this illegal?
generic
type T is private;
CONST_VAL : T;
with procedure PROC (X : access constant T); package Gen_Pack1 is
procedure Try_This;
end Gen_Pack1;
package body Gen_Pack1 is
C : aliased constant T := CONST_VAL;
procedure Try_This is
begin
PROC (C'Access);
end Try_This;
end Gen_Pack1;
package Pack2 is
procedure Modify_The_Constant;
end Pack2;
with Gen_Pack1;
package body Pack2 is
type Rec is record
F1 : Integer;
end record;
procedure Bump (X : access Rec) is
begin
X.F1 := X.F1 + 1;
end Bump;
package Inst is new Gen_Pack1 (Rec, (F1 => 10), Bump);
procedure Modify_The_Constant is
begin
Inst.Try_This;
end Modify_The_Constant;
end Pack2;
****************************************************************
Questions? Ask the ACAA Technical Agent