AI05-019 specifies the conditions under which freezing a subprogram also freezes the profile of the subprogram. Prior to this patch the profile was frozen unconditionally, leading to spurious errors.
Examples in ACATS test BDD2004. Tested on x86_64-pc-linux-gnu, committed on trunk 2016-04-21 Ed Schonberg <schonb...@adacore.com> * freeze.ads, freeze.adb (Freeze_Entity, Freeze_Before): Add boolean parameter to determine whether freezing an overloadable entity freezes its profile as well. This is required by AI05-019. The call to Freeze_Profile within Freeze_Entity is conditioned by the value of this flag, whose default is True. * sem_attr.adb (Resolve_Attribute, case 'Access): The attribute reference freezes the prefix, but it the prefix is a subprogram it does not freeze its profile.
Index: freeze.adb =================================================================== --- freeze.adb (revision 235267) +++ freeze.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2015, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2016, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -1908,9 +1908,17 @@ -- Freeze_Before -- ------------------- - procedure Freeze_Before (N : Node_Id; T : Entity_Id) is - Freeze_Nodes : constant List_Id := Freeze_Entity (T, N); + procedure Freeze_Before + (N : Node_Id; + T : Entity_Id; + F_P : Boolean := True) + is + -- Freeze T, then insert the generated Freeze nodes before the node N. + -- The flag F_P is used when T is an overloadable entity, and indicates + -- whether its profile should be frozen at the same time. + Freeze_Nodes : constant List_Id := Freeze_Entity (T, N, F_P); + begin if Ekind (T) = E_Function then Check_Expression_Function (N, T); @@ -1925,7 +1933,11 @@ -- Freeze_Entity -- ------------------- - function Freeze_Entity (E : Entity_Id; N : Node_Id) return List_Id is + function Freeze_Entity + (E : Entity_Id; + N : Node_Id; + F_P : Boolean := True) return List_Id + is Loc : constant Source_Ptr := Sloc (N); Atype : Entity_Id; Comp : Entity_Id; @@ -4990,12 +5002,13 @@ -- In Ada 2012, freezing a subprogram does not always freeze -- the corresponding profile (see AI05-019). An attribute - -- reference is not a freezing point of the profile. + -- reference is not a freezing point of the profile. The boolean + -- Flag F_P indicates whether the profile should be frozen now. -- Other constructs that should not freeze ??? -- This processing doesn't apply to internal entities (see below) - if not Is_Internal (E) then + if not Is_Internal (E) and then F_P then if not Freeze_Profile (E) then Ghost_Mode := Save_Ghost_Mode; return Result; Index: freeze.ads =================================================================== --- freeze.ads (revision 235192) +++ freeze.ads (working copy) @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2015, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2016, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -187,13 +187,19 @@ -- If Initialization_Statements (E) is an N_Compound_Statement, insert its -- actions in the enclosing list and reset the attribute. - function Freeze_Entity (E : Entity_Id; N : Node_Id) return List_Id; + function Freeze_Entity + (E : Entity_Id; + N : Node_Id; + F_P : Boolean := True) return List_Id; -- Freeze an entity, and return Freeze nodes, to be inserted at the point -- of call. N is a node whose source location corresponds to the freeze -- point. This is used in placing warning messages in the situation where -- it appears that a type has been frozen too early, e.g. when a primitive -- operation is declared after the freezing point of its tagged type. -- Returns No_List if no freeze nodes needed. + -- The defaulted parameter F_P is used when E is a subprogram, and + -- determines whether the profile of the subprogram should be frozen as + -- well. procedure Freeze_All (From : Entity_Id; After : in out Node_Id); -- Before a non-instance body, or at the end of a declarative part, @@ -209,8 +215,13 @@ -- in the scope. It is used to prevent a quadratic traversal over already -- frozen entities. - procedure Freeze_Before (N : Node_Id; T : Entity_Id); + procedure Freeze_Before + (N : Node_Id; + T : Entity_Id; + F_P : Boolean := True); -- Freeze T then Insert the generated Freeze nodes before the node N + -- The flag F_P is used when T is an overloadable entity, and indicates + -- whether its profile should be frozen at the same time. procedure Freeze_Expression (N : Node_Id); -- Freezes the required entities when the Expression N causes freezing. Index: sem_attr.adb =================================================================== --- sem_attr.adb (revision 235267) +++ sem_attr.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2015, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2016, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -10161,18 +10161,20 @@ end loop; -- If Prefix is a subprogram name, this reference freezes, - -- but not if within spec expression mode + -- but not if within spec expression mode. The profile of + -- the subprogram is not frozen at this point. if not In_Spec_Expression then - Freeze_Before (N, Entity (P)); + Freeze_Before (N, Entity (P), False); end if; - -- If it is a type, there is nothing to resolve. If it is an - -- object, complete its resolution. + -- If it is a type, there is nothing to resolve. + -- If it is a subprogram, do not freeze its profile. + -- If it is an object, complete its resolution. elsif Is_Overloadable (Entity (P)) then if not In_Spec_Expression then - Freeze_Before (N, Entity (P)); + Freeze_Before (N, Entity (P), False); end if; -- Nothing to do if prefix is a type name