Commit e895b435 by Ed Schonberg Committed by Arnaud Charlet

sem_ch6.adb (Analyze_Subprogram_Body): If body is a subunit for a different kind…

sem_ch6.adb (Analyze_Subprogram_Body): If body is a subunit for a different kind of stub (possibly wrong name for file)...

2004-10-26  Ed Schonberg  <schonberg@gnat.com>

	* sem_ch6.adb (Analyze_Subprogram_Body): If body is a subunit for a
	different kind of stub (possibly wrong name for file), do not check
	for conformance.
	(Uses_Secondary_Stack): New subsidiary to Build_Body_To_Inline. If body
	includes call to some function that returns an unconstrained type, do
	not inline.

From-SVN: r89671
parent fc4039b9
...@@ -164,7 +164,7 @@ package body Sem_Ch6 is ...@@ -164,7 +164,7 @@ package body Sem_Ch6 is
-- visible entity with that name. -- visible entity with that name.
procedure Install_Entity (E : Entity_Id); procedure Install_Entity (E : Entity_Id);
-- Make single entity visible. Used for generic formals as well. -- Make single entity visible. Used for generic formals as well
procedure Install_Formals (Id : Entity_Id); procedure Install_Formals (Id : Entity_Id);
-- On entry to a subprogram body, make the formals visible. Note -- On entry to a subprogram body, make the formals visible. Note
...@@ -356,7 +356,7 @@ package body Sem_Ch6 is ...@@ -356,7 +356,7 @@ package body Sem_Ch6 is
end loop; end loop;
end if; end if;
-- Visible generic entity is callable within its own body. -- Visible generic entity is callable within its own body
Set_Ekind (Gen_Id, Ekind (Body_Id)); Set_Ekind (Gen_Id, Ekind (Body_Id));
Set_Ekind (Body_Id, E_Subprogram_Body); Set_Ekind (Body_Id, E_Subprogram_Body);
...@@ -366,7 +366,7 @@ package body Sem_Ch6 is ...@@ -366,7 +366,7 @@ package body Sem_Ch6 is
if Nkind (N) = N_Subprogram_Body_Stub then if Nkind (N) = N_Subprogram_Body_Stub then
-- No body to analyze, so restore state of generic unit. -- No body to analyze, so restore state of generic unit
Set_Ekind (Gen_Id, Kind); Set_Ekind (Gen_Id, Kind);
Set_Ekind (Body_Id, Kind); Set_Ekind (Body_Id, Kind);
...@@ -408,7 +408,7 @@ package body Sem_Ch6 is ...@@ -408,7 +408,7 @@ package body Sem_Ch6 is
End_Scope; End_Scope;
Check_Subprogram_Order (N); Check_Subprogram_Order (N);
-- Outside of its body, unit is generic again. -- Outside of its body, unit is generic again
Set_Ekind (Gen_Id, Kind); Set_Ekind (Gen_Id, Kind);
Generate_Reference (Gen_Id, Body_Id, 'b', Set_Ref => False); Generate_Reference (Gen_Id, Body_Id, 'b', Set_Ref => False);
...@@ -661,7 +661,7 @@ package body Sem_Ch6 is ...@@ -661,7 +661,7 @@ package body Sem_Ch6 is
Analyze (P); Analyze (P);
Analyze_Call_And_Resolve; Analyze_Call_And_Resolve;
-- Anything else is an error. -- Anything else is an error
else else
Error_Msg_N ("Invalid procedure or entry call", N); Error_Msg_N ("Invalid procedure or entry call", N);
...@@ -1136,6 +1136,8 @@ package body Sem_Ch6 is ...@@ -1136,6 +1136,8 @@ package body Sem_Ch6 is
if Nkind (Parent (N)) = N_Subunit if Nkind (Parent (N)) = N_Subunit
and then Comes_From_Source (N) and then Comes_From_Source (N)
and then not Error_Posted (Body_Id) and then not Error_Posted (Body_Id)
and then Nkind (Corresponding_Stub (Parent (N))) =
N_Subprogram_Body_Stub
then then
declare declare
Old_Id : constant Entity_Id := Old_Id : constant Entity_Id :=
...@@ -1438,7 +1440,7 @@ package body Sem_Ch6 is ...@@ -1438,7 +1440,7 @@ package body Sem_Ch6 is
then then
Set_Categorization_From_Scope (Designator, Scop); Set_Categorization_From_Scope (Designator, Scop);
else else
-- For a compilation unit, check for library-unit pragmas. -- For a compilation unit, check for library-unit pragmas
New_Scope (Designator); New_Scope (Designator);
Set_Categorization_From_Pragmas (N); Set_Categorization_From_Pragmas (N);
...@@ -1544,7 +1546,7 @@ package body Sem_Ch6 is ...@@ -1544,7 +1546,7 @@ package body Sem_Ch6 is
Stat_Count : Integer := 0; Stat_Count : Integer := 0;
function Has_Excluded_Declaration (Decls : List_Id) return Boolean; function Has_Excluded_Declaration (Decls : List_Id) return Boolean;
-- Check for declarations that make inlining not worthwhile. -- Check for declarations that make inlining not worthwhile
function Has_Excluded_Statement (Stats : List_Id) return Boolean; function Has_Excluded_Statement (Stats : List_Id) return Boolean;
-- Check for statements that make inlining not worthwhile: any -- Check for statements that make inlining not worthwhile: any
...@@ -1564,6 +1566,11 @@ package body Sem_Ch6 is ...@@ -1564,6 +1566,11 @@ package body Sem_Ch6 is
-- Remove it from body to inline. The analysis of the non-inlined -- Remove it from body to inline. The analysis of the non-inlined
-- body will handle the pragma properly. -- body will handle the pragma properly.
function Uses_Secondary_Stack (Bod : Node_Id) return Boolean;
-- If the body of the subprogram includes a call that returns an
-- unconstrained type, the secondary stack is involved, and it
-- is not worth inlining.
------------------------------ ------------------------------
-- Has_Excluded_Declaration -- -- Has_Excluded_Declaration --
------------------------------ ------------------------------
...@@ -1765,6 +1772,40 @@ package body Sem_Ch6 is ...@@ -1765,6 +1772,40 @@ package body Sem_Ch6 is
end loop; end loop;
end Remove_Pragmas; end Remove_Pragmas;
--------------------------
-- Uses_Secondary_Stack --
--------------------------
function Uses_Secondary_Stack (Bod : Node_Id) return Boolean is
function Check_Call (N : Node_Id) return Traverse_Result;
-- Look for function calls that return an unconstrained type
----------------
-- Check_Call --
----------------
function Check_Call (N : Node_Id) return Traverse_Result is
begin
if Nkind (N) = N_Function_Call
and then Is_Entity_Name (Name (N))
and then Is_Composite_Type (Etype (Entity (Name (N))))
and then not Is_Constrained (Etype (Entity (Name (N))))
then
Cannot_Inline
("cannot inline & (call returns unconstrained type)?",
N, Subp);
return Abandon;
else
return OK;
end if;
end Check_Call;
function Check_Calls is new Traverse_Func (Check_Call);
begin
return Check_Calls (Bod) = Abandon;
end Uses_Secondary_Stack;
-- Start of processing for Build_Body_To_Inline -- Start of processing for Build_Body_To_Inline
begin begin
...@@ -1884,13 +1925,21 @@ package body Sem_Ch6 is ...@@ -1884,13 +1925,21 @@ package body Sem_Ch6 is
Remove (Body_To_Analyze); Remove (Body_To_Analyze);
Expander_Mode_Restore; Expander_Mode_Restore;
Set_Body_To_Inline (Decl, Original_Body);
Set_Ekind (Defining_Entity (Original_Body), Ekind (Subp));
Set_Is_Inlined (Subp);
if In_Instance then if In_Instance then
Restore_Env; Restore_Env;
end if; end if;
-- If secondary stk used there is no point in inlining. We have
-- already issued the warning in this case, so nothing to do.
if Uses_Secondary_Stack (Body_To_Analyze) then
return;
end if;
Set_Body_To_Inline (Decl, Original_Body);
Set_Ekind (Defining_Entity (Original_Body), Ekind (Subp));
Set_Is_Inlined (Subp);
end Build_Body_To_Inline; end Build_Body_To_Inline;
------------------- -------------------
...@@ -1910,6 +1959,10 @@ package body Sem_Ch6 is ...@@ -1910,6 +1959,10 @@ package body Sem_Ch6 is
null; null;
elsif Is_Always_Inlined (Subp) then elsif Is_Always_Inlined (Subp) then
-- Remove last character (question mark) to make this into an error,
-- because the Inline_Always pragma cannot be obeyed.
Error_Msg_NE (Msg (1 .. Msg'Length - 1), N, Subp); Error_Msg_NE (Msg (1 .. Msg'Length - 1), N, Subp);
elsif Ineffective_Inline_Warnings then elsif Ineffective_Inline_Warnings then
...@@ -3572,7 +3625,7 @@ package body Sem_Ch6 is ...@@ -3572,7 +3625,7 @@ package body Sem_Ch6 is
-- match explicit actuals with the same value. -- match explicit actuals with the same value.
function FCO (Op_Node, Call_Node : Node_Id) return Boolean; function FCO (Op_Node, Call_Node : Node_Id) return Boolean;
-- Compare an operator node with a function call. -- Compare an operator node with a function call
--------- ---------
-- FCL -- -- FCL --
...@@ -3938,7 +3991,7 @@ package body Sem_Ch6 is ...@@ -3938,7 +3991,7 @@ package body Sem_Ch6 is
-- body is replaced with the discriminal of the enclosing type. -- body is replaced with the discriminal of the enclosing type.
function Conforming_Ranges (R1, R2 : Node_Id) return Boolean; function Conforming_Ranges (R1, R2 : Node_Id) return Boolean;
-- Check both bounds. -- Check both bounds
function Conforming_Bounds (B1, B2 : Node_Id) return Boolean is function Conforming_Bounds (B1, B2 : Node_Id) return Boolean is
begin begin
...@@ -4243,7 +4296,7 @@ package body Sem_Ch6 is ...@@ -4243,7 +4296,7 @@ package body Sem_Ch6 is
B : Entity_Id; B : Entity_Id;
begin begin
-- Check that equality was properly defined. -- Check that equality was properly defined
if No (Next_Formal (First_Formal (S))) then if No (Next_Formal (First_Formal (S))) then
return; return;
...@@ -4773,8 +4826,8 @@ package body Sem_Ch6 is ...@@ -4773,8 +4826,8 @@ package body Sem_Ch6 is
if not Is_Dispatching_Operation (E) then if not Is_Dispatching_Operation (E) then
Set_Is_Immediately_Visible (E, False); Set_Is_Immediately_Visible (E, False);
else else
-- Work done in Override_Dispatching_Operation,
-- work done in Override_Dispatching_Operation. -- so nothing else need to be done here.
null; null;
end if; end if;
...@@ -5201,7 +5254,7 @@ package body Sem_Ch6 is ...@@ -5201,7 +5254,7 @@ package body Sem_Ch6 is
while Present (Formal) loop while Present (Formal) loop
T := Etype (Formal); T := Etype (Formal);
-- We never need an actual subtype for a constrained formal. -- We never need an actual subtype for a constrained formal
if Is_Constrained (T) then if Is_Constrained (T) then
AS_Needed := False; AS_Needed := False;
......
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