===================================================================
@@ -7945,17 +7945,69 @@
-----------------------
procedure Freeze_Subprogram (E : Entity_Id) is
+ procedure Set_Profile_Convention (Subp_Id : Entity_Id);
+ -- Set the conventions of all anonymous access-to-subprogram formals and
+ -- result subtype of subprogram Subp_Id to the convention of Subp_Id.
+
+ ----------------------------
+ -- Set_Profile_Convention --
+ ----------------------------
+
+ procedure Set_Profile_Convention (Subp_Id : Entity_Id) is
+ Conv : constant Convention_Id := Convention (Subp_Id);
+
+ procedure Set_Type_Convention (Typ : Entity_Id);
+ -- Set the convention of anonymous access-to-subprogram type Typ and
+ -- its designated type to Conv.
+
+ -------------------------
+ -- Set_Type_Convention --
+ -------------------------
+
+ procedure Set_Type_Convention (Typ : Entity_Id) is
+ begin
+ -- Set the convention on both the anonymous access-to-subprogram
+ -- type and the subprogram type it points to because both types
+ -- participate in conformance-related checks.
+
+ if Ekind (Typ) = E_Anonymous_Access_Subprogram_Type then
+ Set_Convention (Typ, Conv);
+ Set_Convention (Designated_Type (Typ), Conv);
+ end if;
+ end Set_Type_Convention;
+
+ -- Local variables
+
+ Formal : Entity_Id;
+
+ -- Start of processing for Set_Profile_Convention
+
+ begin
+ Formal := First_Formal (Subp_Id);
+ while Present (Formal) loop
+ Set_Type_Convention (Etype (Formal));
+ Next_Formal (Formal);
+ end loop;
+
+ if Ekind (Subp_Id) = E_Function then
+ Set_Type_Convention (Etype (Subp_Id));
+ end if;
+ end Set_Profile_Convention;
+
+ -- Local variables
+
+ F : Entity_Id;
Retype : Entity_Id;
- F : Entity_Id;
+ -- Start of processing for Freeze_Subprogram
+
begin
-- Subprogram may not have an address clause unless it is imported
if Present (Address_Clause (E)) then
if not Is_Imported (E) then
Error_Msg_N
- ("address clause can only be given " &
- "for imported subprogram",
+ ("address clause can only be given for imported subprogram",
Name (Address_Clause (E)));
end if;
end if;
@@ -7986,8 +8038,8 @@
-- referenced data may change even if the address value does not.
-- Note that if the programmer gave an explicit Pure_Function pragma,
- -- then we believe the programmer, and leave the subprogram Pure.
- -- We also suppress this check on run-time files.
+ -- then we believe the programmer, and leave the subprogram Pure. We
+ -- also suppress this check on run-time files.
if Is_Pure (E)
and then Is_Subprogram (E)
@@ -7997,6 +8049,20 @@
Check_Function_With_Address_Parameter (E);
end if;
+ -- Ensure that all anonymous access-to-subprogram types inherit the
+ -- covention of their related subprogram (RM 6.3.1 13.1/3). This is
+ -- not done for a defaulted convention Ada because those types also
+ -- default to Ada. Convention Protected must not be propagated when
+ -- the subprogram is an entry because this would be illegal. The only
+ -- way to force convention Protected on these kinds of types is to
+ -- include keyword "protected" in the access definition.
+
+ if Convention (E) /= Convention_Ada
+ and then Convention (E) /= Convention_Protected
+ then
+ Set_Profile_Convention (E);
+ end if;
+
-- For non-foreign convention subprograms, this is where we create
-- the extra formals (for accessibility level and constrained bit
-- information). We delay this till the freeze point precisely so
===================================================================
@@ -4870,6 +4870,12 @@
-- in the message, and also provides the location for posting the
-- message in the absence of a specified Err_Loc location.
+ function Conventions_Match
+ (Id1 : Entity_Id;
+ Id2 : Entity_Id) return Boolean;
+ -- Determine whether the conventions of arbitrary entities Id1 and Id2
+ -- match.
+
-----------------------
-- Conformance_Error --
-----------------------
@@ -4929,6 +4935,35 @@
end if;
end Conformance_Error;
+ -----------------------
+ -- Conventions_Match --
+ -----------------------
+
+ function Conventions_Match
+ (Id1 : Entity_Id;
+ Id2 : Entity_Id) return Boolean
+ is
+ begin
+ -- Ignore the conventions of anonymous access-to-subprogram types
+ -- and subprogram types because these are internally generated and
+ -- the only way these may receive a convention is if they inherit
+ -- the convention of a related subprogram.
+
+ if Ekind_In (Id1, E_Anonymous_Access_Subprogram_Type,
+ E_Subprogram_Type)
+ or else
+ Ekind_In (Id2, E_Anonymous_Access_Subprogram_Type,
+ E_Subprogram_Type)
+ then
+ return True;
+
+ -- Otherwise compare the conventions directly
+
+ else
+ return Convention (Id1) = Convention (Id2);
+ end if;
+ end Conventions_Match;
+
-- Local Variables
Old_Type : constant Entity_Id := Etype (Old_Id);
@@ -5015,7 +5050,7 @@
-- entity is inherited.
if Ctype >= Subtype_Conformant then
- if Convention (Old_Id) /= Convention (New_Id) then
+ if not Conventions_Match (Old_Id, New_Id) then
if not Is_Frozen (New_Id) then
null;