diff options
-rw-r--r-- | gcc/ada/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/ada/aspects.ads | 24 | ||||
-rw-r--r-- | gcc/ada/inline.adb | 14 | ||||
-rw-r--r-- | gcc/ada/sem_ch13.adb | 258 |
4 files changed, 177 insertions, 139 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 4721dc8..d3e7897 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,23 @@ +2014-07-30 Hristian Kirtchev <kirtchev@adacore.com> + + * aspects.ads Add a comment explaining why SPARK 2014 aspects are + not delayed. Update the delay status of most SPARK 2014 aspects. + * sem_ch13.adb (Analyze_Aspect_Specifications): Update all calls + to Decorate_Aspect_And_Pragma and Insert_Delayed_Pragma to refert + to Decorate and Insert_Pragma. Add various comments concerning + the delay status of several SPARK 2014 aspects. The insertion + of Refined_State now uses routine Insert_After_SPARK_Mode. + (Decorate): New routine. + (Decorate_Aspect_And_Pragma): Removed. + (Insert_Delayed_Pragma): Removed. + (Insert_Pragma): New routine. + +2014-07-30 Ed Schonberg <schonberg@adacore.com> + + * inline.adb (Expand_Inlined_Call): In GNATprove mode, emit + only a warning, not an error on an attempt to inline a recursive + subprogram. + 2014-07-30 Robert Dewar <dewar@adacore.com> * g-forstr.adb: Minor code reorganization (use J rather than I diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads index 8ddd10b..41fdf7a 100644 --- a/gcc/ada/aspects.ads +++ b/gcc/ada/aspects.ads @@ -543,6 +543,14 @@ package Aspects is -- information from the parent type, which must be frozen at that point -- (since freezing the derived type first freezes the parent type). + -- SPARK 2014 aspects do not follow the general delay mechanism as they + -- act as annotations and cannot modify the attributes of their related + -- constructs. To handle forward references in such aspects, the compiler + -- delays the analysis of their respective pragmas by collecting them in + -- N_Contract nodes. The pragmas are then analyzed at the end of the + -- declarative region which contains the related construct. For details, + -- see routines Analyze_xxx_In_Decl_Part. + -- The following shows which aspects are delayed. There are three cases: type Delay_Type is @@ -593,12 +601,10 @@ package Aspects is Aspect_Asynchronous => Always_Delay, Aspect_Attach_Handler => Always_Delay, Aspect_Constant_Indexing => Always_Delay, - Aspect_Contract_Cases => Always_Delay, Aspect_CPU => Always_Delay, Aspect_Default_Iterator => Always_Delay, Aspect_Default_Value => Always_Delay, Aspect_Default_Component_Value => Always_Delay, - Aspect_Depends => Always_Delay, Aspect_Discard_Names => Always_Delay, Aspect_Dispatching_Domain => Always_Delay, Aspect_Dynamic_Predicate => Always_Delay, @@ -607,15 +613,12 @@ package Aspects is Aspect_External_Tag => Always_Delay, Aspect_Export => Always_Delay, Aspect_Favor_Top_Level => Always_Delay, - Aspect_Global => Always_Delay, Aspect_Implicit_Dereference => Always_Delay, Aspect_Import => Always_Delay, Aspect_Independent => Always_Delay, Aspect_Independent_Components => Always_Delay, Aspect_Inline => Always_Delay, Aspect_Inline_Always => Always_Delay, - Aspect_Initial_Condition => Always_Delay, - Aspect_Initializes => Always_Delay, Aspect_Input => Always_Delay, Aspect_Interrupt_Handler => Always_Delay, Aspect_Interrupt_Priority => Always_Delay, @@ -639,9 +642,6 @@ package Aspects is Aspect_Pure => Always_Delay, Aspect_Pure_Function => Always_Delay, Aspect_Read => Always_Delay, - Aspect_Refined_Depends => Always_Delay, - Aspect_Refined_Global => Always_Delay, - Aspect_Refined_State => Always_Delay, Aspect_Relative_Deadline => Always_Delay, Aspect_Remote_Access_Type => Always_Delay, Aspect_Remote_Call_Interface => Always_Delay, @@ -671,13 +671,21 @@ package Aspects is Aspect_Annotate => Never_Delay, Aspect_Async_Readers => Never_Delay, Aspect_Async_Writers => Never_Delay, + Aspect_Contract_Cases => Never_Delay, Aspect_Convention => Never_Delay, + Aspect_Depends => Never_Delay, Aspect_Dimension => Never_Delay, Aspect_Dimension_System => Never_Delay, Aspect_Effective_Reads => Never_Delay, Aspect_Effective_Writes => Never_Delay, + Aspect_Global => Never_Delay, + Aspect_Initial_Condition => Never_Delay, + Aspect_Initializes => Never_Delay, Aspect_Part_Of => Never_Delay, + Aspect_Refined_Depends => Never_Delay, + Aspect_Refined_Global => Never_Delay, Aspect_Refined_Post => Never_Delay, + Aspect_Refined_State => Never_Delay, Aspect_SPARK_Mode => Never_Delay, Aspect_Synchronization => Never_Delay, Aspect_Test_Case => Never_Delay, diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb index 4e7f8f9..438f27c 100644 --- a/gcc/ada/inline.adb +++ b/gcc/ada/inline.adb @@ -3619,7 +3619,19 @@ package body Inline is A := First_Actual (N); while Present (F) loop if Present (Renamed_Object (F)) then - Error_Msg_N ("cannot inline call to recursive subprogram", N); + + -- If expander is active, it's an error to try to inline a + -- recursive program. In GNATprove mode, just indicate that + -- the inlining will not happen. + + if Expander_Active then + Error_Msg_N ("cannot inline call to recursive subprogram", N); + + else + Cannot_Inline + ("cannot inline call to recursive subprogram?", N, Subp); + end if; + return; end if; diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb index cb3b105..7012941 100644 --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -1185,45 +1185,42 @@ package body Sem_Ch13 is ----------------------------------- procedure Analyze_Aspect_Specifications (N : Node_Id; E : Entity_Id) is - procedure Decorate_Aspect_And_Pragma - (Asp : Node_Id; - Prag : Node_Id; - Delayed : Boolean := False); + procedure Decorate (Asp : Node_Id; Prag : Node_Id); -- Establish the linkages between an aspect and its corresponding - -- pragma. Flag Delayed should be set when both constructs are delayed. + -- pragma. procedure Insert_After_SPARK_Mode (Prag : Node_Id; Ins_Nod : Node_Id; Decls : List_Id); - -- Subsidiary to the analysis of aspects Abstract_State, Initializes and - -- Initial_Condition. Insert node Prag before node Ins_Nod. If Ins_Nod - -- denotes pragma SPARK_Mode, then SPARK_Mode is skipped. Decls is the - -- associated declarative list where Prag is to reside. - - procedure Insert_Delayed_Pragma (Prag : Node_Id); - -- Insert a postcondition-like pragma into the tree depending on the - -- context. Prag must denote one of the following: Pre, Post, Depends, - -- Global or Contract_Cases. This procedure is also used for the case - -- of Attach_Handler which has similar requirements for placement. - - -------------------------------- - -- Decorate_Aspect_And_Pragma -- - -------------------------------- - - procedure Decorate_Aspect_And_Pragma - (Asp : Node_Id; - Prag : Node_Id; - Delayed : Boolean := False) - is + -- Subsidiary to the analysis of aspects Abstract_State, Initializes, + -- Initial_Condition and Refined_State. Insert node Prag before node + -- Ins_Nod. If Ins_Nod denotes pragma SPARK_Mode, then SPARK_Mode is + -- skipped. Decls is the associated declarative list where Prag is to + -- reside. + + procedure Insert_Pragma (Prag : Node_Id); + -- Subsidiary to the analysis of aspects Attach_Handler, Contract_Cases, + -- Depends, Global, Post, Pre, Refined_Depends and Refined_Global. + -- Insert pragma Prag such that it mimics the placement of a source + -- pragma of the same kind. + -- + -- procedure Proc (Formal : ...) with Global => ...; + -- + -- procedure Proc (Formal : ...); + -- pragma Global (...); + + -------------- + -- Decorate -- + -------------- + + procedure Decorate (Asp : Node_Id; Prag : Node_Id) is begin Set_Aspect_Rep_Item (Asp, Prag); Set_Corresponding_Aspect (Prag, Asp); Set_From_Aspect_Specification (Prag); - Set_Is_Delayed_Aspect (Prag, Delayed); - Set_Is_Delayed_Aspect (Asp, Delayed); Set_Parent (Prag, Asp); - end Decorate_Aspect_And_Pragma; + end Decorate; ----------------------------- -- Insert_After_SPARK_Mode -- @@ -1256,12 +1253,13 @@ package body Sem_Ch13 is end if; end Insert_After_SPARK_Mode; - --------------------------- - -- Insert_Delayed_Pragma -- - --------------------------- + ------------------- + -- Insert_Pragma -- + ------------------- - procedure Insert_Delayed_Pragma (Prag : Node_Id) is - Aux : Node_Id; + procedure Insert_Pragma (Prag : Node_Id) is + Aux : Node_Id; + Decl : Node_Id; begin -- When the context is a library unit, the pragma is added to the @@ -1280,29 +1278,30 @@ package body Sem_Ch13 is -- declarative part. elsif Nkind (N) = N_Subprogram_Body then - if No (Declarations (N)) then - Set_Declarations (N, New_List (Prag)); - else - declare - D : Node_Id; - begin + if Present (Declarations (N)) then - -- There may be several aspects associated with the body; - -- preserve the ordering of the corresponding pragmas. + -- Skip other internally generated pragmas from aspects to find + -- the proper insertion point. As a result the order of pragmas + -- is the same as the order of aspects. - D := First (Declarations (N)); - while Present (D) loop - exit when Nkind (D) /= N_Pragma - or else not From_Aspect_Specification (D); - Next (D); - end loop; - - if No (D) then - Append (Prag, Declarations (N)); + Decl := First (Declarations (N)); + while Present (Decl) loop + if Nkind (Decl) = N_Pragma + and then From_Aspect_Specification (Decl) + then + Next (Decl); else - Insert_Before (D, Prag); + exit; end if; - end; + end loop; + + if Present (Decl) then + Insert_Before (Decl, Prag); + else + Append (Prag, Declarations (N)); + end if; + else + Set_Declarations (N, New_List (Prag)); end if; -- Default @@ -1310,7 +1309,7 @@ package body Sem_Ch13 is else Insert_After (N, Prag); end if; - end Insert_Delayed_Pragma; + end Insert_Pragma; -- Local variables @@ -1757,7 +1756,7 @@ package body Sem_Ch13 is Expression => Relocate_Node (Expr))), Pragma_Name => Name_Implemented); - -- Attach Handler + -- Attach_Handler when Aspect_Attach_Handler => Make_Aitem_Pragma @@ -1771,7 +1770,7 @@ package body Sem_Ch13 is -- We need to insert this pragma into the tree to get proper -- processing and to look valid from a placement viewpoint. - Insert_Delayed_Pragma (Aitem); + Insert_Pragma (Aitem); goto Continue; -- Dynamic_Predicate, Predicate, Static_Predicate @@ -2117,7 +2116,7 @@ package body Sem_Ch13 is Make_Pragma_Argument_Association (Loc, Expression => Relocate_Node (Expr))), Pragma_Name => Name_Abstract_State); - Decorate_Aspect_And_Pragma (Aspect, Aitem); + Decorate (Aspect, Aitem); Decls := Visible_Declarations (Specification (Context)); @@ -2176,10 +2175,12 @@ package body Sem_Ch13 is -- Depends - -- Aspect Depends must be delayed because it mentions names - -- of inputs and output that are classified by aspect Global. - -- The aspect and pragma are treated the same way as a post - -- condition. + -- Aspect Depends is never delayed because it is equivalent to + -- a source pragma which appears after the related subprogram. + -- To deal with forward references, the generated pragma is + -- stored in the contract of the related subprogram and later + -- analyzed at the end of the declarative region. See routine + -- Analyze_Depends_In_Decl_Part for details. when Aspect_Depends => Make_Aitem_Pragma @@ -2188,17 +2189,18 @@ package body Sem_Ch13 is Expression => Relocate_Node (Expr))), Pragma_Name => Name_Depends); - Decorate_Aspect_And_Pragma - (Aspect, Aitem, Delayed => True); - Insert_Delayed_Pragma (Aitem); + Decorate (Aspect, Aitem); + Insert_Pragma (Aitem); goto Continue; -- Global - -- Aspect Global must be delayed because it can mention names - -- and benefit from the forward visibility rules applicable to - -- aspects of subprograms. The aspect and pragma are treated - -- the same way as a post condition. + -- Aspect Global is never delayed because it is equivalent to + -- a source pragma which appears after the related subprogram. + -- To deal with forward references, the generated pragma is + -- stored in the contract of the related subprogram and later + -- analyzed at the end of the declarative region. See routine + -- Analyze_Global_In_Decl_Part for details. when Aspect_Global => Make_Aitem_Pragma @@ -2207,25 +2209,28 @@ package body Sem_Ch13 is Expression => Relocate_Node (Expr))), Pragma_Name => Name_Global); - Decorate_Aspect_And_Pragma - (Aspect, Aitem, Delayed => True); - Insert_Delayed_Pragma (Aitem); + Decorate (Aspect, Aitem); + Insert_Pragma (Aitem); goto Continue; -- Initial_Condition - -- Aspect Initial_Condition covers the visible declarations of - -- a package and all hidden states through functions. As such, - -- it must be evaluated at the end of the said declarations. + -- Aspect Initial_Condition is never delayed because it is + -- equivalent to a source pragma which appears after the + -- related package. To deal with forward references, the + -- generated pragma is stored in the contract of the related + -- package and later analyzed at the end of the declarative + -- region. See routine Analyze_Initial_Condition_In_Decl_Part + -- for details. when Aspect_Initial_Condition => Initial_Condition : declare Context : Node_Id := N; Decls : List_Id; begin - -- When aspect Abstract_State appears on a generic package, - -- it is propageted to the package instance. The context in - -- this case is the instance spec. + -- When aspect Initial_Condition appears on a generic + -- package, it is propageted to the package instance. The + -- context in this case is the instance spec. if Nkind (Context) = N_Package_Instantiation then Context := Instance_Spec (Context); @@ -2242,9 +2247,7 @@ package body Sem_Ch13 is Expression => Relocate_Node (Expr))), Pragma_Name => Name_Initial_Condition); - - Decorate_Aspect_And_Pragma - (Aspect, Aitem, Delayed => True); + Decorate (Aspect, Aitem); if No (Decls) then Decls := New_List; @@ -2272,9 +2275,12 @@ package body Sem_Ch13 is -- Initializes - -- Aspect Initializes coverts the visible declarations of a - -- package. As such, it must be evaluated at the end of the - -- said declarations. + -- Aspect Initializes is never delayed because it is equivalent + -- to a source pragma appearing after the related package. To + -- deal with forward references, the generated pragma is stored + -- in the contract of the related package and later analyzed at + -- the end of the declarative region. For details, see routine + -- Analyze_Initializes_In_Decl_Part. when Aspect_Initializes => Initializes : declare Context : Node_Id := N; @@ -2299,9 +2305,7 @@ package body Sem_Ch13 is Make_Pragma_Argument_Association (Loc, Expression => Relocate_Node (Expr))), Pragma_Name => Name_Initializes); - - Decorate_Aspect_And_Pragma - (Aspect, Aitem, Delayed => True); + Decorate (Aspect, Aitem); if No (Decls) then Decls := New_List; @@ -2362,7 +2366,7 @@ package body Sem_Ch13 is -- emulate the behavior of a source pragma. if Nkind (N) = N_Package_Body then - Decorate_Aspect_And_Pragma (Aspect, Aitem); + Decorate (Aspect, Aitem); Decls := Declarations (N); @@ -2379,7 +2383,7 @@ package body Sem_Ch13 is -- declarations to emulate the behavior of a source pragma. elsif Nkind (N) = N_Package_Declaration then - Decorate_Aspect_And_Pragma (Aspect, Aitem); + Decorate (Aspect, Aitem); Decls := Visible_Declarations (Specification (N)); @@ -2395,10 +2399,13 @@ package body Sem_Ch13 is -- Refined_Depends - -- Aspect Refined_Depends must be delayed because it can - -- mention state refinements introduced by aspect Refined_State - -- and further classified by aspect Refined_Global. Since both - -- those aspects are delayed, so is Refined_Depends. + -- Aspect Refined_Depends is never delayed because it is + -- equivalent to a source pragma which appears in the + -- declarations of the related subprogram body. To deal with + -- forward references, the generated pragma is stored in the + -- contract of the related subprogram body and later analyzed + -- at the end of the declarative region. For details, see + -- routine Analyze_Refined_Depends_In_Decl_Part. when Aspect_Refined_Depends => Make_Aitem_Pragma @@ -2407,17 +2414,19 @@ package body Sem_Ch13 is Expression => Relocate_Node (Expr))), Pragma_Name => Name_Refined_Depends); - Decorate_Aspect_And_Pragma - (Aspect, Aitem, Delayed => True); - Insert_Delayed_Pragma (Aitem); + Decorate (Aspect, Aitem); + Insert_Pragma (Aitem); goto Continue; -- Refined_Global - -- Aspect Refined_Global must be delayed because it can mention - -- state refinements introduced by aspect Refined_State. Since - -- Refined_State is already delayed due to forward references, - -- so is Refined_Global. + -- Aspect Refined_Global is never delayed because it is + -- equivalent to a source pragma which appears in the + -- declarations of the related subprogram body. To deal with + -- forward references, the generated pragma is stored in the + -- contract of the related subprogram body and later analyzed + -- at the end of the declarative region. For details, see + -- routine Analyze_Refined_Global_In_Decl_Part. when Aspect_Refined_Global => Make_Aitem_Pragma @@ -2426,8 +2435,8 @@ package body Sem_Ch13 is Expression => Relocate_Node (Expr))), Pragma_Name => Name_Refined_Global); - Decorate_Aspect_And_Pragma (Aspect, Aitem, Delayed => True); - Insert_Delayed_Pragma (Aitem); + Decorate (Aspect, Aitem); + Insert_Pragma (Aitem); goto Continue; -- Refined_Post @@ -2442,7 +2451,6 @@ package body Sem_Ch13 is -- Refined_State when Aspect_Refined_State => Refined_State : declare - Decl : Node_Id; Decls : List_Id; begin @@ -2452,38 +2460,29 @@ package body Sem_Ch13 is -- the pragma. if Nkind (N) = N_Package_Body then + Decls := Declarations (N); + Make_Aitem_Pragma (Pragma_Argument_Associations => New_List ( Make_Pragma_Argument_Association (Loc, Expression => Relocate_Node (Expr))), Pragma_Name => Name_Refined_State); - Decorate_Aspect_And_Pragma (Aspect, Aitem); - - Decls := Declarations (N); - - -- When the package body is subject to pragma SPARK_Mode, - -- insert pragma Refined_State after SPARK_Mode. + Decorate (Aspect, Aitem); - if Present (Decls) then - Decl := First (Decls); - - if Nkind (Decl) = N_Pragma - and then Pragma_Name (Decl) = Name_SPARK_Mode - then - Insert_After (Decl, Aitem); - - -- The related package body lacks SPARK_Mode, the - -- corresponding pragma must be the first declaration. - - else - Prepend_To (Decls, Aitem); - end if; + if No (Decls) then + Decls := New_List; + Set_Declarations (N, Decls); + end if; - -- Otherwise the pragma forms a new declarative list + -- Pragma Refined_State must be inserted after pragma + -- SPARK_Mode in the tree. This ensures that any error + -- messages dependent on SPARK_Mode will be properly + -- enabled/suppressed. - else - Set_Declarations (N, New_List (Aitem)); - end if; + Insert_After_SPARK_Mode + (Prag => Aitem, + Ins_Nod => First (Decls), + Decls => Decls); else Error_Msg_NE @@ -2741,7 +2740,7 @@ package body Sem_Ch13 is -- about delay issues, since the pragmas themselves deal -- with delay of visibility for the expression analysis. - Insert_Delayed_Pragma (Aitem); + Insert_Pragma (Aitem); goto Continue; end Pre_Post; @@ -2821,9 +2820,8 @@ package body Sem_Ch13 is Expression => Relocate_Node (Expr))), Pragma_Name => Nam); - Decorate_Aspect_And_Pragma - (Aspect, Aitem, Delayed => True); - Insert_Delayed_Pragma (Aitem); + Decorate (Aspect, Aitem); + Insert_Pragma (Aitem); goto Continue; -- Case 5: Special handling for aspects with an optional @@ -3022,7 +3020,7 @@ package body Sem_Ch13 is -- the aspect specification node. if Present (Aitem) then - Set_From_Aspect_Specification (Aitem, True); + Set_From_Aspect_Specification (Aitem); end if; -- In the context of a compilation unit, we directly put the |