From 17fd72cef4060b14c2cf363726261f820fdcab10 Mon Sep 17 00:00:00 2001 From: Ed Schonberg Date: Thu, 21 Apr 2016 08:21:47 +0000 Subject: [PATCH] sem_ch6.adb (Analyze_Subprogram_Body_Helper): If the body is created for SPARK_To_C... 2016-04-21 Ed Schonberg * sem_ch6.adb (Analyze_Subprogram_Body_Helper): If the body is created for SPARK_To_C, the entity must remain invisible so it does not overload subsequent references to the original function. * exp_ch6.adb (Build_Procedure_Body_Form, Replace_Returns): Handle Extended_Return_Statements by replacing it with a block with assignments and a simple return statement. * exp_util.adb (Build_Procedure_Form): Make procedure entity invisible after analyzing declaration, to prevent improper overloading. From-SVN: r235306 --- gcc/ada/ChangeLog | 12 ++++++++++++ gcc/ada/exp_ch6.adb | 32 ++++++++++++++++++++++++++++++++ gcc/ada/exp_util.adb | 12 ++++++++++-- gcc/ada/sem_ch6.adb | 9 +++++++-- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index d725805d646..1383b3a959f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,15 @@ +2016-04-21 Ed Schonberg + + * sem_ch6.adb (Analyze_Subprogram_Body_Helper): If the body is + created for SPARK_To_C, the entity must remain invisible so it + does not overload subsequent references to the original function. + * exp_ch6.adb (Build_Procedure_Body_Form, Replace_Returns): + Handle Extended_Return_Statements by replacing it with a block + with assignments and a simple return statement. + * exp_util.adb (Build_Procedure_Form): Make procedure entity + invisible after analyzing declaration, to prevent improper + overloading. + 2016-04-21 Javier Miranda * sem_ch6.adb (Build_Subprogram_Declaration): Propagate the diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index d1232543492..4dcd4e9d8a6 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -692,6 +692,38 @@ package body Exp_Ch6 is end loop; end; + elsif Nkind (Stmt) = N_Extended_Return_Statement then + declare + Ret_Obj : constant Entity_Id := + Defining_Entity + (First (Return_Object_Declarations (Stmt))); + Assign : constant Node_Id := + Make_Assignment_Statement (Sloc (Stmt), + Name => + New_Occurrence_Of (Param_Id, Loc), + Expression => + New_Occurrence_Of (Ret_Obj, Sloc (Stmt))); + Stmts : constant List_Id := + Statements (Handled_Statement_Sequence (Stmt)); + + begin + Set_Assignment_OK (Name (Assign)); + + Rewrite (Stmt, + Make_Block_Statement (Sloc (Stmt), + Declarations => + Return_Object_Declarations (Stmt), + Handled_Statement_Sequence => + Make_Handled_Sequence_Of_Statements (Loc, + Statements => + Statements (Handled_Statement_Sequence (Stmt))))); + + Replace_Returns (Param_Id, Stmts); + + Append_To (Stmts, Assign); + Append_To (Stmts, Make_Simple_Return_Statement (Loc)); + end; + elsif Nkind (Stmt) = N_If_Statement then Replace_Returns (Param_Id, Then_Statements (Stmt)); Replace_Returns (Param_Id, Else_Statements (Stmt)); diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index dfc8e883dbd..13773faa915 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -929,6 +929,7 @@ package body Exp_Util is Func_Formal : Entity_Id; Proc_Formals : List_Id; + Proc_Decl : Node_Id; begin -- No action needed if this transformation was already done @@ -969,13 +970,20 @@ package body Exp_Util is -- function declaration. The processing in Build_Procedure_Body_Form -- relies on this order. - Insert_After_And_Analyze (Unit_Declaration_Node (Subp), + Proc_Decl := Make_Subprogram_Declaration (Loc, Specification => Make_Procedure_Specification (Loc, Defining_Unit_Name => Make_Defining_Identifier (Loc, Chars (Subp)), - Parameter_Specifications => Proc_Formals))); + Parameter_Specifications => Proc_Formals)); + + Insert_After_And_Analyze (Unit_Declaration_Node (Subp), Proc_Decl); + + -- Entity of procedure must remain invisible so that it does not + -- overload subsequent references to the original function. + + Set_Is_Immediately_Visible (Defining_Entity (Proc_Decl), False); -- Mark the function as having a procedure form diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index 19a65489bf9..fe1c898bd18 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -4138,9 +4138,14 @@ package body Sem_Ch6 is -- that carries the return value. if Present (Cloned_Body_For_C) then - Rewrite (N, - Build_Procedure_Body_Form (Spec_Id, Cloned_Body_For_C)); + Rewrite (N, Build_Procedure_Body_Form (Spec_Id, Cloned_Body_For_C)); Analyze (N); + + -- The entity for the created procedure must remain invisible, so it + -- does not participate in resolution of subsequent references to the + -- function. + + Set_Is_Immediately_Visible (Corresponding_Spec (N), False); end if; Ghost_Mode := Save_Ghost_Mode; -- 2.30.2