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.

Reply via email to