!standard 6.3.1(16/2) 10-04-02 AI05-0207-1/02 !class binding interpretation 10-02-15 !status Amendment 2012 10-04-02 !status ARG Approved 9-0-1 10-02-28 !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; -- Now illegal. 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) @drepl Two profiles are @i 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. @dby Two profiles are @i if they are type conformant, 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; ****************************************************************