Commit 7bf911b5 by Hristian Kirtchev Committed by Arnaud Charlet

re PR ada/66242 (Front-end error if exception propagation disabled)

2015-11-18  Hristian Kirtchev  <kirtchev@adacore.com>

	PR ada/66242

	* exp_ch3.adb (Default_Initialize_Object): Reimplemented. Abort
	defer / undefer pairs are now encapsulated in a block with
	an AT END handler. Partial finalization now takes restriction
	No_Exception_Propagation into account when generating blocks.
	* exp_ch7.adb Various reformattings.
	(Create_Finalizer): Change
	the generation of abort defer / undefer pairs and explain the
	lack of an AT END handler.
	(Process_Transient_Objects): Add generation of abort defer/undefer
	pairs.
	* exp_ch9.adb Various reformattings.
	(Build_Protected_Subprogram_Body): Use
	Build_Runtime_Call to construct a call to Abort_Defer.
	(Build_Protected_Subprogram_Call_Cleanup): Use
	Build_Runtime_Call to construct a call to Abort_Undefer.
	(Expand_N_Asynchronous_Select): Use Build_Runtime_Call to
	construct a call to Abort_Defer.
	* exp_intr.adb (Expand_Unc_Deallocation): Abort defer
	/ undefer pairs are now encapsulated in a block with
	an AT END handler. Finalization now takes restriction
	No_Exception_Propagation into account when generating blocks.
	* exp_util.ads, exp_util.adb (Wrap_Cleanup_Procedure): Removed.

From-SVN: r230531
parent 8ebcad86
...@@ -4315,14 +4315,17 @@ package body Exp_Ch9 is ...@@ -4315,14 +4315,17 @@ package body Exp_Ch9 is
if Nkind (Op_Spec) = N_Function_Specification then if Nkind (Op_Spec) = N_Function_Specification then
if Exc_Safe then if Exc_Safe then
R := Make_Temporary (Loc, 'R'); R := Make_Temporary (Loc, 'R');
Unprot_Call := Unprot_Call :=
Make_Object_Declaration (Loc, Make_Object_Declaration (Loc,
Defining_Identifier => R, Defining_Identifier => R,
Constant_Present => True, Constant_Present => True,
Object_Definition => New_Copy (Result_Definition (N_Op_Spec)), Object_Definition =>
New_Copy (Result_Definition (N_Op_Spec)),
Expression => Expression =>
Make_Function_Call (Loc, Make_Function_Call (Loc,
Name => Make_Identifier (Loc, Name =>
Make_Identifier (Loc,
Chars => Chars (Defining_Unit_Name (N_Op_Spec))), Chars => Chars (Defining_Unit_Name (N_Op_Spec))),
Parameter_Associations => Uactuals)); Parameter_Associations => Uactuals));
...@@ -4331,8 +4334,10 @@ package body Exp_Ch9 is ...@@ -4331,8 +4334,10 @@ package body Exp_Ch9 is
Expression => New_Occurrence_Of (R, Loc)); Expression => New_Occurrence_Of (R, Loc));
else else
Unprot_Call := Make_Simple_Return_Statement (Loc, Unprot_Call :=
Expression => Make_Function_Call (Loc, Make_Simple_Return_Statement (Loc,
Expression =>
Make_Function_Call (Loc,
Name => Name =>
Make_Identifier (Loc, Make_Identifier (Loc,
Chars => Chars (Defining_Unit_Name (N_Op_Spec))), Chars => Chars (Defining_Unit_Name (N_Op_Spec))),
...@@ -4354,7 +4359,8 @@ package body Exp_Ch9 is ...@@ -4354,7 +4359,8 @@ package body Exp_Ch9 is
-- Wrap call in block that will be covered by an at_end handler -- Wrap call in block that will be covered by an at_end handler
if not Exc_Safe then if not Exc_Safe then
Unprot_Call := Make_Block_Statement (Loc, Unprot_Call :=
Make_Block_Statement (Loc,
Handled_Statement_Sequence => Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc, Make_Handled_Sequence_Of_Statements (Loc,
Statements => New_List (Unprot_Call))); Statements => New_List (Unprot_Call)));
...@@ -4385,15 +4391,14 @@ package body Exp_Ch9 is ...@@ -4385,15 +4391,14 @@ package body Exp_Ch9 is
Selector_Name => Make_Identifier (Loc, Name_uObject)), Selector_Name => Make_Identifier (Loc, Name_uObject)),
Attribute_Name => Name_Unchecked_Access); Attribute_Name => Name_Unchecked_Access);
Lock_Stmt := Make_Procedure_Call_Statement (Loc, Lock_Stmt :=
Make_Procedure_Call_Statement (Loc,
Name => Lock_Name, Name => Lock_Name,
Parameter_Associations => New_List (Object_Parm)); Parameter_Associations => New_List (Object_Parm));
if Abort_Allowed then if Abort_Allowed then
Stmts := New_List ( Stmts := New_List (
Make_Procedure_Call_Statement (Loc, Build_Runtime_Call (Loc, RE_Abort_Defer),
Name => New_Occurrence_Of (RTE (RE_Abort_Defer), Loc),
Parameter_Associations => Empty_List),
Lock_Stmt); Lock_Stmt);
else else
...@@ -4417,12 +4422,13 @@ package body Exp_Ch9 is ...@@ -4417,12 +4422,13 @@ package body Exp_Ch9 is
Build_Protected_Subprogram_Call_Cleanup (Op_Spec, Pid, Loc, Stmts); Build_Protected_Subprogram_Call_Cleanup (Op_Spec, Pid, Loc, Stmts);
if Nkind (Op_Spec) = N_Function_Specification then if Nkind (Op_Spec) = N_Function_Specification then
Append (Return_Stmt, Stmts); Append_To (Stmts, Return_Stmt);
Append (Make_Block_Statement (Loc, Append_To (Pre_Stmts,
Make_Block_Statement (Loc,
Declarations => New_List (Unprot_Call), Declarations => New_List (Unprot_Call),
Handled_Statement_Sequence => Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc, Make_Handled_Sequence_Of_Statements (Loc,
Statements => Stmts)), Pre_Stmts); Statements => Stmts)));
Stmts := Pre_Stmts; Stmts := Pre_Stmts;
end if; end if;
end if; end if;
...@@ -4594,11 +4600,7 @@ package body Exp_Ch9 is ...@@ -4594,11 +4600,7 @@ package body Exp_Ch9 is
-- Abort_Undefer; -- Abort_Undefer;
if Abort_Allowed then if Abort_Allowed then
Append_To (Stmts, Append_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Undefer));
Make_Procedure_Call_Statement (Loc,
Name =>
New_Occurrence_Of (RTE (RE_Abort_Undefer), Loc),
Parameter_Associations => Empty_List));
end if; end if;
end Build_Protected_Subprogram_Call_Cleanup; end Build_Protected_Subprogram_Call_Cleanup;
...@@ -7169,6 +7171,8 @@ package body Exp_Ch9 is ...@@ -7169,6 +7171,8 @@ package body Exp_Ch9 is
Name => New_Occurrence_Of (Proc, Loc))); Name => New_Occurrence_Of (Proc, Loc)));
end Rewrite_Abortable_Part; end Rewrite_Abortable_Part;
-- Start of processing for Expand_N_Asynchronous_Select
begin begin
Process_Statements_For_Controlled_Objects (Trig); Process_Statements_For_Controlled_Objects (Trig);
Process_Statements_For_Controlled_Objects (Abrt); Process_Statements_For_Controlled_Objects (Abrt);
...@@ -7426,8 +7430,7 @@ package body Exp_Ch9 is ...@@ -7426,8 +7430,7 @@ package body Exp_Ch9 is
Name_uDisp_Asynchronous_Select), Name_uDisp_Asynchronous_Select),
Loc), Loc),
Parameter_Associations => Parameter_Associations => New_List (
New_List (
New_Copy_Tree (Obj), -- <object> New_Copy_Tree (Obj), -- <object>
New_Occurrence_Of (S, Loc), -- S New_Occurrence_Of (S, Loc), -- S
Make_Attribute_Reference (Loc, -- P'Address Make_Attribute_Reference (Loc, -- P'Address
...@@ -7439,10 +7442,7 @@ package body Exp_Ch9 is ...@@ -7439,10 +7442,7 @@ package body Exp_Ch9 is
-- Generate: -- Generate:
-- Abort_Defer; -- Abort_Defer;
Prepend_To (TaskE_Stmts, Prepend_To (TaskE_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
Make_Procedure_Call_Statement (Loc,
Name => New_Occurrence_Of (RTE (RE_Abort_Defer), Loc),
Parameter_Associations => No_List));
-- Generate: -- Generate:
-- Abort_Undefer; -- Abort_Undefer;
...@@ -7450,10 +7450,8 @@ package body Exp_Ch9 is ...@@ -7450,10 +7450,8 @@ package body Exp_Ch9 is
Cleanup_Stmts := New_Copy_List_Tree (Astats); Cleanup_Stmts := New_Copy_List_Tree (Astats);
Prepend_To (Cleanup_Stmts, Prepend_To
Make_Procedure_Call_Statement (Loc, (Cleanup_Stmts, Build_Runtime_Call (Loc, RE_Abort_Undefer));
Name => New_Occurrence_Of (RTE (RE_Abort_Undefer), Loc),
Parameter_Associations => No_List));
-- Wrap the statements in a block. Exp_Ch7.Expand_Cleanup_Actions -- Wrap the statements in a block. Exp_Ch7.Expand_Cleanup_Actions
-- will generate a _clean for the additional status flag. -- will generate a _clean for the additional status flag.
...@@ -7640,9 +7638,7 @@ package body Exp_Ch9 is ...@@ -7640,9 +7638,7 @@ package body Exp_Ch9 is
Hdle := New_List (Build_Abort_Block_Handler (Loc)); Hdle := New_List (Build_Abort_Block_Handler (Loc));
Prepend_To (Astats, Prepend_To (Astats, Build_Runtime_Call (Loc, RE_Abort_Undefer));
Make_Procedure_Call_Statement (Loc,
Name => New_Occurrence_Of (RTE (RE_Abort_Undefer), Loc)));
Abortable_Block := Abortable_Block :=
Make_Block_Statement (Loc, Make_Block_Statement (Loc,
...@@ -7788,17 +7784,14 @@ package body Exp_Ch9 is ...@@ -7788,17 +7784,14 @@ package body Exp_Ch9 is
Has_Created_Identifier => True, Has_Created_Identifier => True,
Is_Asynchronous_Call_Block => True); Is_Asynchronous_Call_Block => True);
if Exception_Mechanism = Back_End_Exceptions then -- Aborts are not deferred at beginning of exception handlers in
-- ZCX.
-- Aborts are not deferred at beginning of exception handlers
-- in ZCX.
if Exception_Mechanism = Back_End_Exceptions then
Handler_Stmt := Make_Null_Statement (Loc); Handler_Stmt := Make_Null_Statement (Loc);
else else
Handler_Stmt := Make_Procedure_Call_Statement (Loc, Handler_Stmt := Build_Runtime_Call (Loc, RE_Abort_Undefer);
Name => New_Occurrence_Of (RTE (RE_Abort_Undefer), Loc),
Parameter_Associations => No_List);
end if; end if;
Stmts := New_List ( Stmts := New_List (
...@@ -7881,9 +7874,7 @@ package body Exp_Ch9 is ...@@ -7881,9 +7874,7 @@ package body Exp_Ch9 is
Hdle := New_List (Build_Abort_Block_Handler (Loc)); Hdle := New_List (Build_Abort_Block_Handler (Loc));
Prepend_To (Astats, Prepend_To (Astats, Build_Runtime_Call (Loc, RE_Abort_Undefer));
Make_Procedure_Call_Statement (Loc,
Name => New_Occurrence_Of (RTE (RE_Abort_Undefer), Loc)));
Abortable_Block := Abortable_Block :=
Make_Block_Statement (Loc, Make_Block_Statement (Loc,
...@@ -7927,10 +7918,7 @@ package body Exp_Ch9 is ...@@ -7927,10 +7918,7 @@ package body Exp_Ch9 is
-- Protected the call against abort -- Protected the call against abort
Prepend_To (Stmts, Prepend_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
Make_Procedure_Call_Statement (Loc,
Name => New_Occurrence_Of (RTE (RE_Abort_Defer), Loc),
Parameter_Associations => Empty_List));
end if; end if;
Set_Entry_Cancel_Parameter (Blk_Ent, Cancel_Param); Set_Entry_Cancel_Parameter (Blk_Ent, Cancel_Param);
...@@ -10762,9 +10750,7 @@ package body Exp_Ch9 is ...@@ -10762,9 +10750,7 @@ package body Exp_Ch9 is
-- analysis with unknown calls, so don't do it. -- analysis with unknown calls, so don't do it.
if not CodePeer_Mode then if not CodePeer_Mode then
Call := Call := Build_Runtime_Call (Loc, RE_Abort_Undefer);
Make_Procedure_Call_Statement (Eloc,
Name => New_Occurrence_Of (RTE (RE_Abort_Undefer), Eloc));
Insert_Before Insert_Before
(First (Statements (Handled_Statement_Sequence (First (Statements (Handled_Statement_Sequence
(Accept_Statement (Alt)))), (Accept_Statement (Alt)))),
......
...@@ -1022,6 +1022,7 @@ package body Exp_Intr is ...@@ -1022,6 +1022,7 @@ package body Exp_Intr is
Abrt_Blk : Node_Id := Empty; Abrt_Blk : Node_Id := Empty;
Abrt_Blk_Id : Entity_Id; Abrt_Blk_Id : Entity_Id;
Abrt_HSS : Node_Id;
AUD : Entity_Id; AUD : Entity_Id;
Fin_Blk : Node_Id; Fin_Blk : Node_Id;
Fin_Call : Node_Id; Fin_Call : Node_Id;
...@@ -1031,10 +1032,6 @@ package body Exp_Intr is ...@@ -1031,10 +1032,6 @@ package body Exp_Intr is
Gen_Code : Node_Id; Gen_Code : Node_Id;
Obj_Ref : Node_Id; Obj_Ref : Node_Id;
Dummy : Entity_Id;
-- This variable captures an unused dummy internal entity, see the
-- comment associated with its use.
begin begin
-- Nothing to do if we know the argument is null -- Nothing to do if we know the argument is null
...@@ -1048,10 +1045,10 @@ package body Exp_Intr is ...@@ -1048,10 +1045,10 @@ package body Exp_Intr is
-- Ex : Exception_Occurrence; -- Ex : Exception_Occurrence;
-- Raised : Boolean := False; -- Raised : Boolean := False;
-- begin -- aborts allowed -- begin
-- Abort_Defer; -- Abort_Defer;
-- begin -- exception propagation allowed -- begin
-- [Deep_]Finalize (Obj_Ref); -- [Deep_]Finalize (Obj_Ref);
-- exception -- exception
...@@ -1121,7 +1118,13 @@ package body Exp_Intr is ...@@ -1121,7 +1118,13 @@ package body Exp_Intr is
Exception_Handlers => New_List ( Exception_Handlers => New_List (
Build_Exception_Handler (Fin_Data)))); Build_Exception_Handler (Fin_Data))));
-- The finalization action must be protected by an abort defer -- Otherwise exception propagation is not allowed
else
Fin_Blk := Fin_Call;
end if;
-- The finalization action must be protected by an abort defer and
-- undefer pair when aborts are allowed. Generate: -- undefer pair when aborts are allowed. Generate:
-- begin -- begin
...@@ -1134,37 +1137,32 @@ package body Exp_Intr is ...@@ -1134,37 +1137,32 @@ package body Exp_Intr is
if Abort_Allowed then if Abort_Allowed then
AUD := RTE (RE_Abort_Undefer_Direct); AUD := RTE (RE_Abort_Undefer_Direct);
Abrt_Blk := Abrt_HSS :=
Make_Block_Statement (Loc,
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc, Make_Handled_Sequence_Of_Statements (Loc,
Statements => New_List ( Statements => New_List (
Build_Runtime_Call (Loc, RE_Abort_Defer), Build_Runtime_Call (Loc, RE_Abort_Defer),
Fin_Blk), Fin_Blk),
At_End_Proc => New_Occurrence_Of (AUD, Loc))); At_End_Proc => New_Occurrence_Of (AUD, Loc));
Abrt_Blk :=
Make_Block_Statement (Loc,
Handled_Statement_Sequence => Abrt_HSS);
Add_Block_Identifier (Abrt_Blk, Abrt_Blk_Id); Add_Block_Identifier (Abrt_Blk, Abrt_Blk_Id);
Expand_At_End_Handler (Abrt_HSS, Abrt_Blk_Id);
-- Present the Abort_Undefer_Direct function to the backend so -- Present the Abort_Undefer_Direct function to the backend so
-- that it can inline the call to the function. -- that it can inline the call to the function.
Add_Inlined_Body (AUD, N); Add_Inlined_Body (AUD, N);
Append_To (Stmts, Abrt_Blk);
-- Otherwise aborts are not allowed. Generate a dummy entity to -- Otherwise aborts are not allowed
-- ensure that the internal symbols are in sync when a unit is
-- compiled with and without aborts.
else else
Dummy := New_Internal_Entity (E_Block, Current_Scope, Loc, 'B'); Abrt_Blk := Fin_Blk;
Append_To (Stmts, Fin_Blk);
end if; end if;
-- Otherwise exception propagation is not allowed Append_To (Stmts, Abrt_Blk);
else
Append_To (Stmts, Fin_Call);
end if;
end if; end if;
-- For a task type, call Free_Task before freeing the ATCB. We used to -- For a task type, call Free_Task before freeing the ATCB. We used to
...@@ -1174,8 +1172,8 @@ package body Exp_Intr is ...@@ -1174,8 +1172,8 @@ package body Exp_Intr is
-- (the task will be freed once it terminates). -- (the task will be freed once it terminates).
if Is_Task_Type (Desig_Typ) then if Is_Task_Type (Desig_Typ) then
Append_To Append_To (Stmts,
(Stmts, Cleanup_Task (N, Duplicate_Subexpr_No_Checks (Arg))); Cleanup_Task (N, Duplicate_Subexpr_No_Checks (Arg)));
-- For composite types that contain tasks, recurse over the structure -- For composite types that contain tasks, recurse over the structure
-- to build the selectors for the task subcomponents. -- to build the selectors for the task subcomponents.
...@@ -1411,15 +1409,6 @@ package body Exp_Intr is ...@@ -1411,15 +1409,6 @@ package body Exp_Intr is
Rewrite (N, Gen_Code); Rewrite (N, Gen_Code);
Analyze (N); Analyze (N);
-- If we generated a block with an At_End_Proc, expand the exception
-- handler. We need to wait until after everything else is analyzed.
if Present (Abrt_Blk) then
Expand_At_End_Handler
(HSS => Handled_Statement_Sequence (Abrt_Blk),
Blk_Id => Entity (Identifier (Abrt_Blk)));
end if;
end Expand_Unc_Deallocation; end Expand_Unc_Deallocation;
----------------------- -----------------------
......
...@@ -9453,19 +9453,4 @@ package body Exp_Util is ...@@ -9453,19 +9453,4 @@ package body Exp_Util is
and then not Is_Predicate_Function_M (S); and then not Is_Predicate_Function_M (S);
end Within_Internal_Subprogram; end Within_Internal_Subprogram;
----------------------------
-- Wrap_Cleanup_Procedure --
----------------------------
procedure Wrap_Cleanup_Procedure (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Stseq : constant Node_Id := Handled_Statement_Sequence (N);
Stmts : constant List_Id := Statements (Stseq);
begin
if Abort_Allowed then
Prepend_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
Append_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Undefer));
end if;
end Wrap_Cleanup_Procedure;
end Exp_Util; end Exp_Util;
...@@ -1020,15 +1020,6 @@ package Exp_Util is ...@@ -1020,15 +1020,6 @@ package Exp_Util is
-- predefined primitive operation. Some expansion activity (e.g. predicate -- predefined primitive operation. Some expansion activity (e.g. predicate
-- checks) is disabled in such. -- checks) is disabled in such.
procedure Wrap_Cleanup_Procedure (N : Node_Id);
-- Given an N_Subprogram_Body node, this procedure adds an Abort_Defer call
-- at the start of the statement sequence, and an Abort_Undefer call at the
-- end of the statement sequence. All cleanup routines (i.e. those that are
-- called from "at end" handlers) must defer abort on entry and undefer
-- abort on exit. Note that it is assumed that the code for the procedure
-- does not contain any return statements which would allow the flow of
-- control to escape doing the undefer call.
private private
pragma Inline (Duplicate_Subexpr); pragma Inline (Duplicate_Subexpr);
pragma Inline (Force_Evaluation); pragma Inline (Force_Evaluation);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment