Ada 2005 allows the declaration of an access to function whose return type is itself an access to function, etc. Each anonymous access type generated for this pathological construct has a scope which is the scope of the current declaration.
The following must compile quietly in Ada 2005 mode, and output: It works It works It works --- with Text_IO; use Text_IO; function G return Integer is procedure Proc is begin Put_Line ("It works"); end Proc; function G0 return access procedure is begin return Proc'access; end; function G1 return access function return access procedure is begin return G0'access; end G1; function G2 return access function return access function return access procedure is begin return G1'access; end G2; begin G0.all; G1.all.all; G2.all.all.all; return 0; end; Tested on x86_64-pc-linux-gnu, committed on trunk 2011-11-21 Ed Schonberg <schonb...@adacore.com> * sem_ch3.adb (Access_Definition): If the access definition is itself the return type of an access to function definition which is ultimately the return type of an access to subprogram declaration, its scope is the enclosing scope of the ultimate access to subprogram.
Index: sem_ch3.adb =================================================================== --- sem_ch3.adb (revision 181567) +++ sem_ch3.adb (working copy) @@ -726,13 +726,33 @@ -- If the access definition is the return type of another access to -- function, scope is the current one, because it is the one of the - -- current type declaration. + -- current type declaration, except for the pathological case below. if Nkind_In (Related_Nod, N_Object_Declaration, N_Access_Function_Definition) then Anon_Scope := Current_Scope; + -- A pathological case: function returning access functions that + -- return access functions, etc. Each anonymous access type created + -- is in the enclosing scope of the outermost function. + + declare + Par : Node_Id; + begin + Par := Related_Nod; + while Nkind_In (Par, + N_Access_Function_Definition, + N_Access_Definition) + loop + Par := Parent (Par); + end loop; + + if Nkind (Par) = N_Function_Specification then + Anon_Scope := Scope (Defining_Entity (Par)); + end if; + end; + -- For the anonymous function result case, retrieve the scope of the -- function specification's associated entity rather than using the -- current scope. The current scope will be the function itself if the