https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93702
--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Marc Poulhies <[email protected]>: https://gcc.gnu.org/g:dc5689c9c077d6ae7fa7d4eff6293ccf5be67ac4 commit r17-742-gdc5689c9c077d6ae7fa7d4eff6293ccf5be67ac4 Author: Eric Botcazou <[email protected]> Date: Tue Jan 13 20:00:28 2026 +0100 ada: Fix early freezing of tagged type by expression function in nested package This addresses a long-standing issue in the implementation of expression functions of Ada 2012, pertaining to their interaction with the freezing of types that are referenced in their expression: when they are used as the completion of a function declaration, their expression causes these types to become frozen, but when they are stand-alone, it does not. The last rule is problematic for GNAT, because it goes against its freezing model devised for Ada 95, where types must always be frozen for code to be generated. Therefore the current implementation needs to resort to several kludges in order to implement it, but these are not bullet proof and do not always work when tagged types are involved. The new approach is to insert the generated body of stand-alone expression functions at the next freezing point, instead of at the end of the current package. This makes a difference for nested packages, which are precisely the problematic case. This requires the analysis and resolution performed on the body, potentially out of context now, to give identical results as the preanalysis and resolution performed on the expression in its context, which is achieved by treating the generated body as an inlined body. This approach requires a more complete implementation of the special rules for freezing expression functions, so the change overhauls it and plugs the most blatant loopholes of the current implementation. gcc/ada/ChangeLog: PR ada/93702 * contracts.adb (Analyze_Entry_Or_Subprogram_Contract): Call Freeze_Expr_Types_Before instead of Freeze_Expr_Types. (Process_Preconditions_For): Likewise. * exp_ch3.adb (Make_Controlling_Function_Wrappers): Do not set Was_Expression_Function flag on the generated bodies. * exp_ch6.adb (Expand_Call_Helper): Call Original_Node on the result of the call to Expression_Of_Expression_Function. * freeze.ads (Freeze_Expr_Types): Delete. (Freeze_Expr_Types_Before): New procedure declaration. * freeze.adb (Check_Expression_Function): Delete. (Freeze_And_Append): Add Do_Freeze_Profile formal parameter and pass it to Freeze_Entity. Remove call to Check_Expression_Function. (Freeze_Entity): Set Test_E consistently and freeze the expression of expression functions that are primitives of a tagged type. (Freeze_Profile): Adjust calls to Should_Freeze_Type. (In_Expanded_Body): Also return true for DIC procedures. (Freeze_Expression): Remove call to Check_Expression_Function. Freeze the expression of expression functions. (Freeze_Expr_Types): Add Result and Before formal parameters. Make a copy and preanalyze/resolve it only if Typ is present. (Freeze_Expr_Types.Explain_Error): New procedure. (Freeze_Expr_Types.Find_Incomplete_Constant): Likewise. (Freeze_Expr_Types.Check_And_Freeze_Type): Return immediately if the type is already frozen. Report errors on N instead of Node. If Before is False, append the freeze nodes to Result. (Freeze_Expr_Types.Freeze_Type_Refs): Call Find_Incomplete_Constant. (Freeze_Expr_Types_Before): New procedure. (Should_Freeze_Type): Remove formal parameter E and specific kludge for stand-alone expression functions. * ghost.ads (Mark_And_Set_Ghost_Body_Of_Expression_Function): New procedure declaration. * ghost.adb (Mark_And_Set_Ghost_Body_Of_Expression_Function): New procedure body. * rtsfind.adb (RTE): Preserve and reset the In_Inlined_Body flag. (RTE_Record_Component): Likewise. * sem_attr.adb (Resolve_Attribute) <Attribute_Access>: Just call Freeze_Expression to freeze the expression of prefixes that are expression functions and remove obsolete implementation. * sem_ch3.adb (Analyze_Declarations): Adjust commentary. (Check_Completion): Also skip stand-alone expressions functions. * sem_ch4.adb (Analyze_Case_Expression): Always analyze the choices. * sem_ch6.adb: Add with and use clauses for Sem_Ch7. (Analyze_Expression_Function): Call Freeze_Expr_Types_Before instead of Freeze_Expr_Types for expression functions that are completions. For stand-alone expression functions, set In_Private_Part on the entity if it is in the private part, propagate the results of the resolution of the specification of the the declaration to that of the body and insert the body at the next freezing point. (Analyze_Subprogram_Body_Helper): Remove the machinery for masking and unmasking unfrozen types. For a stand-alone expression function, call Mark_And_Set_Ghost_Body_Of_Expression_Function, remove obsolete code dealing with the freezing of the spec, set In_Inlined_Body to True, make the full view of the private types of its scope visible if this is not the current scope and it is in the private part, and avoid making the spec immediately visible. (Analyze_Subprogram_Specification): Fix typo. (New_Overloaded_Entity): Set Has_Completion on a [generic] package that conflicts with the entity to prevent a cascaded error. * sem_ch7.ads (Is_Private_Base_Type): New function declaration moved here from... * sem_ch7.adb (Is_Private_Base_Type): ...here. Remove. * sem_ch8.adb (Analyze_Subprogram_Renaming): Call Freeze_Expression to freeze the expression of expression functions, but only if the renaming comes from source. * sem_ch12.adb (Analyze_One_Association): Likewise, and remove the manual freezing for calls to them. * sem_res.adb (Resolve): Remove obsolete commentary. (Resolve_Call): Always freeze the expression of names that are expression functions. * sem_util.adb (Check_Fully_Declared): Add commentary and do not check types with private component declared outside of the current scope when it is a generic unit. (Expression_Of_Expression_Function): Return Expression directly. (Is_Inlinable_Expression_Function): Call Original_Node on the result of the call to Expression_Of_Expression_Function.
