This patch fixes a bug where finalization code might refer to variables
outside their lifetime. The previous version moved declarations into the
Handled_Statement_Sequence (HSS), so that the "at end" handler of the
HSS could handle exceptions raised by those declarations. The
First_Real_Statement field was used to find the first statement after
the moved declarations. In addition, if the HSS already had exception
handlers, it was wrapped in another layer of block_statement. This
doesn't work if there are variable-sized objects allocated on the
(primary) stack, because the stack will be popped before the "at end" is
invoked.

In the new version, we allow "at end" on nodes such as
N_Subprogram_Body, in addition to HSS. We modify gigi so that such an
"at end" applies to the whole body (declarations and HSS) by extending
support for At_End_Proc mechanism to N_Block_Statement and N_*_Body
nodes. This also removes the support for First_Real_Statement. In
particular, an exception raised by the declarations will trigger the "at
end". We no longer move declarations into the HSS, we no longer have a
First_Real_Statement field, and we no longer do the wrapping mentioned
above.

This change requires various other changes, in cases where we depended
on the First_Real_Statement and the moving/wrapping mentioned above.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

        * gen_il-fields.ads
        (First_Real_Statement): Remove this field.
        * gen_il-gen-gen_nodes.adb: Remove the First_Real_Statement field.
        Add the At_End_Proc field to nodes that have both Declarations and
        HSS.
        * sinfo.ads
        (At_End_Proc): Document new semantics.
        (First_Real_Statement): Remove comment.
        * exp_ch11.adb
        (Expand_N_Handled_Sequence_Of_Statements): Remove
        First_Real_Statement.
        * exp_ch7.adb
        (Build_Cleanup_Statements): Remove "Historical note"; it doesn't
        seem useful, and we have revision history.
        (Create_Finalizer): Insert the finalizer later, typically in the
        statement list, in some cases.
        (Build_Finalizer_Call): Attach the "at end" handler to the parent
        of the HSS node in most cases, so it applies to declarations.
        (Expand_Cleanup_Actions): Remove Wrap_HSS_In_Block and the call to
        it. Remove the code that moves declarations. Remove some redundant
        code.
        * exp_ch9.adb
        (Build_Protected_Entry): Copy the At_End_Proc.
        (Build_Protected_Subprogram_Body): Reverse the sense of Exc_Safe,
        to avoid double negatives. Remove "Historical note" as in
        exp_ch7.adb.
        (Build_Unprotected_Subprogram_Body): Copy the At_End_Proc from the
        protected version.
        (Expand_N_Conditional_Entry_Call): Use First (Statements(...))
        instead of First_Real_Statement(...).
        (Expand_N_Task_Body): Put the Abort_Undefer call at the beginning
        of the declarations, rather than in the HSS. Use First
        (Statements(...)) instead of First_Real_Statement(...). Copy the
        At_End_Proc.
        * inline.adb
        (Has_Initialized_Type): Return False if the declaration does not
        come from source.
        * libgnarl/s-tpoben.ads
        (Lock_Entries, Lock_Entries_With_Status): Document when these
        things raise Program_Error. It's not clear that
        Lock_Entries_With_Status ought to be raising exceptions, but at
        least it's documented now.
        * sem.ads: Minor comment fixes.
        * sem_ch6.adb
        (Analyze_Subprogram_Body_Helper): Use First (Statements(...))
        instead of First_Real_Statement(...).
        (Analyze_Null_Procedure): Minor comment fix.
        * sem_util.adb
        (Might_Raise): Return True for N_Raise_Expression. Adjust the part
        about exceptions generated by the back end to match the reality of
        what the back end generates.
        (Update_First_Real_Statement): Remove.
        * sem_util.ads: Remove First_Real_Statement from comment.
        * sinfo-utils.ads
        (First_Real_Statement): New function that always returns Empty.
        This should be removed once gnat-llvm and codepeer have been
        updated to not refer to First_Real_Statement.
        * sprint.adb
        (Sprint_At_End_Proc): Deal with printing At_End_Proc.
        * sem_prag.adb: Minor comment fixes.
        * gcc-interface/trans.cc (At_End_Proc_to_gnu): New function.
        (Subprogram_Body_to_gnu): Call it to handle an At_End_Proc.
        (Handled_Sequence_Of_Statements_to_gnu): Likewise. Remove the
        support for First_Real_Statement and clean up the rest.
        (Exception_Handler_to_gnu): Do not push binding levels.
        (Compilation_Unit_to_gnu): Adjust call to process_decls.
        (gnat_to_gnu) <N_Package_Specification>: Likewise. <N_Entry_Body>:
        Likewise. <N_Freeze_Entity>: Likewise. <N_Block_Statement>:
        Likewise and call At_End_Proc_to_gnu to handle an At_End_Proc.
        <N_Package_Body>: Likewise.
        (process_decls): Remove GNAT_END_LIST parameter and adjust
        recursive calls.

Co-authored-by: Eric Botcazou <ebotca...@adacore.com>

Attachment: patch.diff.gz
Description: application/gzip

Reply via email to