From patchwork Thu Jun 17 15:24:44 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Ada] Freezing the designated type of an access_to_subprogram_type Date: Thu, 17 Jun 2010 05:24:44 -0000 From: Arnaud Charlet X-Patchwork-Id: 56061 Message-Id: <20100617152444.GA14164@adacore.com> To: gcc-patches@gcc.gnu.org Cc: Ed Schonberg A type cannot be frozen if it is not yet fully defined. For the designated type of an access_to_subprogram_type, all the types in its profile must be fully defined before the subprogram type itself can be frozen. The following must compile quietly: --- with Statefull_Artifact_G; procedure Main is type State is (CREATED, REVIEWED); type Activity is (REVIEW); package Requirement is new Statefull_Artifact_G (State, Activity, State'First); begin null; end Main; --- with Ada.Finalization; generic type State is (<>); type Activity is (<>); Initial_State : State := State'First; package Statefull_Artifact_G is type Statefull_Artifact is abstract new Ada.Finalization.Controlled with private; type Guard is access function (This : Statefull_Artifact'Class) return Boolean; private type State_Ref is access all State; type Guard_Map is array (State, Activity) of Guard; Guards : Guard_Map := (others => (others => null)); type Statefull_Artifact is abstract new Ada.Finalization.Controlled with record Current_State : State_Ref := null; end record; end Statefull_Artifact_G; Tested on x86_64-pc-linux-gnu, committed on trunk 2010-06-17 Ed Schonberg * freeze.adb (Freeze_Expression): The designated type of an access_to_suprogram type can only be frozen if all types in its profile are fully defined. Index: freeze.adb =================================================================== --- freeze.adb (revision 160905) +++ freeze.adb (working copy) @@ -5306,6 +5306,26 @@ package body Freeze is return True; end; + -- For the designated type of an access to subprogram. all types in + -- the profile must be fully defined. + + elsif Ekind (T) = E_Subprogram_Type then + declare + F : Entity_Id; + + begin + F := First_Formal (T); + while Present (F) loop + if not Is_Fully_Defined (Etype (F)) then + return False; + end if; + + Next_Formal (F); + end loop; + + return Is_Fully_Defined (Etype (T)); + end; + else return not Is_Private_Type (T) or else Present (Full_View (Base_Type (T)));