Commit 98f01d53 by Arnaud Charlet

exp_ch6.adb (Expand_Call): Add comment on handling of back end intrinsic

	* exp_ch6.adb (Expand_Call): Add comment on handling of back end
	intrinsic

	* exp_intr.adb (Expand_Intrinsic_Call): Ignore unrecognized intrinsic,
	leaving call unchanged.
	This deals with the case where the pragma Import specified
	an external name, to be handled by the back end.

	* sem_prag.adb (Process_Import_Or_Interface): Do not check validity of
	subprogram which is Imported with convention Intrinsic if an
	External_Name argument is specified.
	(Process_Import_Or_Interface): Properly diagnose link name argument.
	(Inlining_Not_Possible): New name for Cannot_Inline, to avoid confusion
	with Sem_Ch6.Cannot_Inline.
	(Process_Inline): Provide separate warning for inapplicable inline
	pragma.
	(Cannot_Inline): Reject subprograms that have an at_end handler, so that
	treatment is uniform on different targets.

From-SVN: r91882
parent 2717634d
...@@ -1051,7 +1051,7 @@ package body Exp_Ch6 is ...@@ -1051,7 +1051,7 @@ package body Exp_Ch6 is
end if; end if;
end if; end if;
-- The call node itself is re-analyzed in Expand_Call. -- The call node itself is re-analyzed in Expand_Call
end Expand_Actuals; end Expand_Actuals;
...@@ -1974,6 +1974,10 @@ package body Exp_Ch6 is ...@@ -1974,6 +1974,10 @@ package body Exp_Ch6 is
-- appropriate expansion to the corresponding tree node and we -- appropriate expansion to the corresponding tree node and we
-- are all done (since after that the call is gone!) -- are all done (since after that the call is gone!)
-- In the case where the intrinsic is to be processed by the back end,
-- the call to Expand_Intrinsic_Call will do nothing, which is fine,
-- since the idea in this case is to pass the call unchanged.
if Is_Intrinsic_Subprogram (Subp) then if Is_Intrinsic_Subprogram (Subp) then
Expand_Intrinsic_Call (N, Subp); Expand_Intrinsic_Call (N, Subp);
return; return;
...@@ -2300,7 +2304,7 @@ package body Exp_Ch6 is ...@@ -2300,7 +2304,7 @@ package body Exp_Ch6 is
Temp_Typ : Entity_Id; Temp_Typ : Entity_Id;
procedure Make_Exit_Label; procedure Make_Exit_Label;
-- Build declaration for exit label to be used in Return statements. -- Build declaration for exit label to be used in Return statements
function Process_Formals (N : Node_Id) return Traverse_Result; function Process_Formals (N : Node_Id) return Traverse_Result;
-- Replace occurrence of a formal with the corresponding actual, or -- Replace occurrence of a formal with the corresponding actual, or
...@@ -2331,7 +2335,7 @@ package body Exp_Ch6 is ...@@ -2331,7 +2335,7 @@ package body Exp_Ch6 is
procedure Make_Exit_Label is procedure Make_Exit_Label is
begin begin
-- Create exit label for subprogram, if one doesn't exist yet. -- Create exit label for subprogram if one does not exist yet
if No (Exit_Lab) then if No (Exit_Lab) then
Lab_Id := Make_Identifier (Loc, New_Internal_Name ('L')); Lab_Id := Make_Identifier (Loc, New_Internal_Name ('L'));
...@@ -2509,15 +2513,13 @@ package body Exp_Ch6 is ...@@ -2509,15 +2513,13 @@ package body Exp_Ch6 is
elsif Nkind (N) = N_Identifier elsif Nkind (N) = N_Identifier
and then Nkind (Parent (Entity (N))) = N_Object_Declaration and then Nkind (Parent (Entity (N))) = N_Object_Declaration
then then
-- The block assigns the result of the call to the temporary
-- The block assigns the result of the call to the temporary.
Insert_After (Parent (Entity (N)), Blk); Insert_After (Parent (Entity (N)), Blk);
elsif Nkind (Parent (N)) = N_Assignment_Statement elsif Nkind (Parent (N)) = N_Assignment_Statement
and then Is_Entity_Name (Name (Parent (N))) and then Is_Entity_Name (Name (Parent (N)))
then then
-- Replace assignment with the block -- Replace assignment with the block
declare declare
...@@ -2660,7 +2662,7 @@ package body Exp_Ch6 is ...@@ -2660,7 +2662,7 @@ package body Exp_Ch6 is
Set_Declarations (Blk, New_List); Set_Declarations (Blk, New_List);
end if; end if;
-- If this is a derived function, establish the proper return type. -- If this is a derived function, establish the proper return type
if Present (Orig_Subp) if Present (Orig_Subp)
and then Orig_Subp /= Subp and then Orig_Subp /= Subp
...@@ -2797,7 +2799,7 @@ package body Exp_Ch6 is ...@@ -2797,7 +2799,7 @@ package body Exp_Ch6 is
Targ := Name (Parent (N)); Targ := Name (Parent (N));
else else
-- Replace call with temporary, and create its declaration. -- Replace call with temporary and create its declaration
Temp := Temp :=
Make_Defining_Identifier (Loc, New_Internal_Name ('C')); Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
...@@ -2815,7 +2817,7 @@ package body Exp_Ch6 is ...@@ -2815,7 +2817,7 @@ package body Exp_Ch6 is
end if; end if;
end if; end if;
-- Traverse the tree and replace formals with actuals or their thunks. -- Traverse the tree and replace formals with actuals or their thunks.
-- Attach block to tree before analysis and rewriting. -- Attach block to tree before analysis and rewriting.
Replace_Formals (Blk); Replace_Formals (Blk);
...@@ -2879,7 +2881,7 @@ package body Exp_Ch6 is ...@@ -2879,7 +2881,7 @@ package body Exp_Ch6 is
Restore_Env; Restore_Env;
-- Cleanup mapping between formals and actuals, for other expansions. -- Cleanup mapping between formals and actuals for other expansions
F := First_Formal (Subp); F := First_Formal (Subp);
...@@ -3493,9 +3495,9 @@ package body Exp_Ch6 is ...@@ -3493,9 +3495,9 @@ package body Exp_Ch6 is
end loop; end loop;
end if; end if;
-- For a function, we must deal with the case where there is at -- For a function, we must deal with the case where there is at least
-- least one missing return. What we do is to wrap the entire body -- one missing return. What we do is to wrap the entire body of the
-- of the function in a block: -- function in a block:
-- begin -- begin
-- ... -- ...
...@@ -3732,7 +3734,7 @@ package body Exp_Ch6 is ...@@ -3732,7 +3734,7 @@ package body Exp_Ch6 is
if Is_Subprogram (Proc) if Is_Subprogram (Proc)
and then Proc /= Corr and then Proc /= Corr
then then
-- Protected function or procedure. -- Protected function or procedure
Set_Entity (Rec, Param); Set_Entity (Rec, Param);
......
...@@ -281,12 +281,21 @@ package body Exp_Intr is ...@@ -281,12 +281,21 @@ package body Exp_Intr is
then then
Expand_Source_Info (N, Nam); Expand_Source_Info (N, Nam);
else -- If we have a renaming, expand the call to the original operation,
-- Only other possibility is a renaming, in which case we expand -- which must itself be intrinsic, since renaming requires matching
-- the call to the original operation (which must be intrinsic). -- conventions and this has already been checked.
pragma Assert (Present (Alias (E))); elsif Present (Alias (E)) then
Expand_Intrinsic_Call (N, Alias (E)); Expand_Intrinsic_Call (N, Alias (E));
-- The only other case is where an external name was specified,
-- since this is the only way that an otherwise unrecognized
-- name could escape the checking in Sem_Prag. Nothing needs
-- to be done in such a case, since we pass such a call to the
-- back end unchanged.
else
null;
end if; end if;
end Expand_Intrinsic_Call; end Expand_Intrinsic_Call;
......
...@@ -2965,13 +2965,34 @@ package body Sem_Prag is ...@@ -2965,13 +2965,34 @@ package body Sem_Prag is
else else
Set_Imported (Def_Id); Set_Imported (Def_Id);
-- If Import intrinsic, set intrinsic flag and verify -- Special processing for Convention_Intrinsic
-- that it is known as such.
if C = Convention_Intrinsic then if C = Convention_Intrinsic then
-- Link_Name argument not allowed for intrinsic
if Present (Arg3)
and then Chars (Arg3) = Name_Link_Name
then
Arg4 := Arg3;
end if;
if Present (Arg4) then
Error_Pragma_Arg
("Link_Name argument not allowed for " &
"Import Intrinsic",
Arg4);
end if;
Set_Is_Intrinsic_Subprogram (Def_Id); Set_Is_Intrinsic_Subprogram (Def_Id);
Check_Intrinsic_Subprogram
(Def_Id, Expression (Arg2)); -- If no external name is present, then check that
-- this is a valid intrinsic subprogram. If an external
-- name is present, then this is handled by the back end.
if No (Arg3) then
Check_Intrinsic_Subprogram (Def_Id, Expression (Arg2));
end if;
end if; end if;
-- All interfaced procedures need an external symbol -- All interfaced procedures need an external symbol
...@@ -3073,24 +3094,29 @@ package body Sem_Prag is ...@@ -3073,24 +3094,29 @@ package body Sem_Prag is
procedure Set_Inline_Flags (Subp : Entity_Id); procedure Set_Inline_Flags (Subp : Entity_Id);
-- Sets Is_Inlined and Has_Pragma_Inline flags for Subp -- Sets Is_Inlined and Has_Pragma_Inline flags for Subp
function Cannot_Inline (Subp : Entity_Id) return Boolean; function Inlining_Not_Possible (Subp : Entity_Id) return Boolean;
-- Do not set the inline flag if body is available and contains -- Returns True if it can be determined at this stage that inlining
-- exception handlers, to prevent undefined symbols at link time. -- is not possible, for examle if the body is available and contains
-- Emit warning if front-end inlining is enabled and the pragma -- exception handlers, we prevent inlining, since otherwise we can
-- appears too late. -- get undefined symbols at link time. This function also emits a
-- warning if front-end inlining is enabled and the pragma appears
-- too late.
-- ??? is business with link symbols still valid, or does it relate
-- to front end ZCX which is being phased out ???
------------------- ---------------------------
-- Cannot_Inline -- -- Inlining_Not_Possible --
------------------- ---------------------------
function Cannot_Inline (Subp : Entity_Id) return Boolean is function Inlining_Not_Possible (Subp : Entity_Id) return Boolean is
Decl : constant Node_Id := Unit_Declaration_Node (Subp); Decl : constant Node_Id := Unit_Declaration_Node (Subp);
Stats : Node_Id;
begin begin
if Nkind (Decl) = N_Subprogram_Body then if Nkind (Decl) = N_Subprogram_Body then
return Stats := Handled_Statement_Sequence (Decl);
Present return Present (Exception_Handlers (Stats))
(Exception_Handlers (Handled_Statement_Sequence (Decl))); or else Present (At_End_Proc (Stats));
elsif Nkind (Decl) = N_Subprogram_Declaration elsif Nkind (Decl) = N_Subprogram_Declaration
and then Present (Corresponding_Body (Decl)) and then Present (Corresponding_Body (Decl))
...@@ -3112,18 +3138,22 @@ package body Sem_Prag is ...@@ -3112,18 +3138,22 @@ package body Sem_Prag is
return False; return False;
else else
Stats :=
Handled_Statement_Sequence
(Unit_Declaration_Node (Corresponding_Body (Decl)));
return return
Present (Exception_Handlers Present (Exception_Handlers (Stats))
(Handled_Statement_Sequence or else Present (At_End_Proc (Stats));
(Unit_Declaration_Node (Corresponding_Body (Decl)))));
end if; end if;
else else
-- If body is not available, assume the best, the check is -- If body is not available, assume the best, the check is
-- performed again when compiling enclosing package bodies. -- performed again when compiling enclosing package bodies.
return False; return False;
end if; end if;
end Cannot_Inline; end Inlining_Not_Possible;
----------------- -----------------
-- Make_Inline -- -- Make_Inline --
...@@ -3137,8 +3167,10 @@ package body Sem_Prag is ...@@ -3137,8 +3167,10 @@ package body Sem_Prag is
if Etype (Subp) = Any_Type then if Etype (Subp) = Any_Type then
return; return;
elsif Cannot_Inline (Subp) then -- If inlining is not possible, for now do not treat as an error
Applies := True; -- Do not treat as an error.
elsif Inlining_Not_Possible (Subp) then
Applies := True;
return; return;
-- Here we have a candidate for inlining, but we must exclude -- Here we have a candidate for inlining, but we must exclude
...@@ -3277,8 +3309,13 @@ package body Sem_Prag is ...@@ -3277,8 +3309,13 @@ package body Sem_Prag is
elsif not Effective elsif not Effective
and then Warn_On_Redundant_Constructs and then Warn_On_Redundant_Constructs
then then
Error_Msg_NE ("pragma Inline for& is redundant?", if Inlining_Not_Possible (Subp) then
N, Entity (Subp_Id)); Error_Msg_NE
("pragma Inline for& is ignored?", N, Entity (Subp_Id));
else
Error_Msg_NE
("pragma Inline for& is redundant?", N, Entity (Subp_Id));
end if;
end if; end if;
Next (Assoc); Next (Assoc);
......
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