diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-02-25 15:05:39 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-02-25 15:05:39 +0000 |
commit | 334d1dbea30a398c5095983f7b6dfdd851bfee12 (patch) | |
tree | 48f255ef070ad622be4207d83e6991472e576211 | |
parent | 2e44583dfbd498287b4f3d0b486a16eda9f8f9e7 (diff) | |
download | gcc-334d1dbea30a398c5095983f7b6dfdd851bfee12.tar.gz |
2014-02-25 Hristian Kirtchev <kirtchev@adacore.com>
* exp_ch6.adb (Add_Or_Save_Precondition): New routine.
(Collect_Body_Postconditions_In_Decls): New routine.
(Collect_Body_Postconditions_Of_Kind): Factor out code. Handle
postcondition aspects or pragmas that appear on a subprogram
body stub.
(Collect_Spec_Preconditions): Factor out code. Handle
precondition aspects or pragmas that appear on a subprogram
body stub.
* sem_ch6.adb (Analyze_Subprogram_Body_Helper): The analysis of
aspects that apply to a subprogram body stub is no longer delayed,
the aspects are analyzed on the spot.
(SPARK_Aspect_Error):
Aspects that apply to a subprogram declaration cannot appear in
a subunit.
* sem_ch10.adb Remove with and use clause for Sem_Ch13.
(Analyze_Proper_Body): Add local variable Comp_Unit. Unum
is now a local variable. Code cleanup. Analysis related to
the aspects of a subprogram body stub is now carried out by
Analyze_Subprogram_Body_Helper. Do not propagate the aspects
and/or pragmas of a subprogram body stub to the proper body
as this is no longer needed. Do not analyze the aspects of a
subprogram stub when the corresponding source unit is missing.
(Analyze_Protected_Body_Stub): Flag the illegal use of aspects
on a stub.
(Analyze_Task_Body_Stub): Flag the illegal use of
aspects on a stub.
(Optional_Subunit): Add local variable Unum.
* sem_ch13.adb (Insert_Delayed_Pragma): Do not analyze a generated
pragma when it applies to a subprogram body stub.
* sem_prag.adb (Analyze_Pragma): Pragmas Contract_Cases,
Depends and Global can now apply to a subprogram body stub as
long as it acts as its own spec.
(Analyze_Refined_Pragma):
Code reformatting. Refinement pragmas cannot apply to a subunit.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@208134 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ada/ChangeLog | 37 | ||||
-rw-r--r-- | gcc/ada/exp_ch6.adb | 193 | ||||
-rw-r--r-- | gcc/ada/sem_ch10.adb | 126 | ||||
-rw-r--r-- | gcc/ada/sem_ch13.adb | 8 | ||||
-rw-r--r-- | gcc/ada/sem_ch6.adb | 31 | ||||
-rw-r--r-- | gcc/ada/sem_prag.adb | 98 |
6 files changed, 323 insertions, 170 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index ed288b3d053..ad3b82d2086 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,42 @@ 2014-02-25 Hristian Kirtchev <kirtchev@adacore.com> + * exp_ch6.adb (Add_Or_Save_Precondition): New routine. + (Collect_Body_Postconditions_In_Decls): New routine. + (Collect_Body_Postconditions_Of_Kind): Factor out code. Handle + postcondition aspects or pragmas that appear on a subprogram + body stub. + (Collect_Spec_Preconditions): Factor out code. Handle + precondition aspects or pragmas that appear on a subprogram + body stub. + * sem_ch6.adb (Analyze_Subprogram_Body_Helper): The analysis of + aspects that apply to a subprogram body stub is no longer delayed, + the aspects are analyzed on the spot. + (SPARK_Aspect_Error): + Aspects that apply to a subprogram declaration cannot appear in + a subunit. + * sem_ch10.adb Remove with and use clause for Sem_Ch13. + (Analyze_Proper_Body): Add local variable Comp_Unit. Unum + is now a local variable. Code cleanup. Analysis related to + the aspects of a subprogram body stub is now carried out by + Analyze_Subprogram_Body_Helper. Do not propagate the aspects + and/or pragmas of a subprogram body stub to the proper body + as this is no longer needed. Do not analyze the aspects of a + subprogram stub when the corresponding source unit is missing. + (Analyze_Protected_Body_Stub): Flag the illegal use of aspects + on a stub. + (Analyze_Task_Body_Stub): Flag the illegal use of + aspects on a stub. + (Optional_Subunit): Add local variable Unum. + * sem_ch13.adb (Insert_Delayed_Pragma): Do not analyze a generated + pragma when it applies to a subprogram body stub. + * sem_prag.adb (Analyze_Pragma): Pragmas Contract_Cases, + Depends and Global can now apply to a subprogram body stub as + long as it acts as its own spec. + (Analyze_Refined_Pragma): + Code reformatting. Refinement pragmas cannot apply to a subunit. + +2014-02-25 Hristian Kirtchev <kirtchev@adacore.com> + * einfo.ads Update the usage of flag Uses_Sec_Stack. Uses_Sec_Stack now applies to E_Loop entities. * exp_ch5.adb (Expand_Iterator_Loop): The temporary for a cursor diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index 5ffea6acc3f..4aa43ba10d5 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -8671,58 +8671,100 @@ package body Exp_Ch6 is procedure Collect_Body_Postconditions (Stmts : in out List_Id) is procedure Collect_Body_Postconditions_Of_Kind (Post_Nam : Name_Id); - -- Process postconditions of a particular kind denoted by Post_Nam + -- Process all postconditions of a particular kind denoted by + -- Post_Nam. ----------------------------------------- -- Collect_Body_Postconditions_Of_Kind -- ----------------------------------------- procedure Collect_Body_Postconditions_Of_Kind (Post_Nam : Name_Id) is - Check_Prag : Node_Id; - Decl : Node_Id; + procedure Collect_Body_Postconditions_In_Decls + (First_Decl : Node_Id); + -- Process all postconditions found in a declarative list starting + -- with declaration First_Decl. - begin - pragma Assert (Nam_In (Post_Nam, Name_Postcondition, - Name_Refined_Post)); + ------------------------------------------ + -- Collect_Body_Postconditions_In_Decls -- + ------------------------------------------ - -- Inspect the declarations of the subprogram body looking for a - -- pragma that matches the desired name. + procedure Collect_Body_Postconditions_In_Decls + (First_Decl : Node_Id) + is + Check_Prag : Node_Id; + Decl : Node_Id; - Decl := First (Declarations (N)); - while Present (Decl) loop - if Nkind (Decl) = N_Pragma then - if Pragma_Name (Decl) = Post_Nam then - Analyze (Decl); - Check_Prag := Build_Pragma_Check_Equivalent (Decl); + begin + -- Inspect the declarative list looking for a pragma that + -- matches the desired name. - if Expander_Active then - Append_Enabled_Item - (Item => Check_Prag, - List => Stmts); + Decl := First_Decl; + while Present (Decl) loop - -- When analyzing a generic unit, save the pragma for - -- later. + -- Note that non-matching pragmas are skipped - else - Prepend_To_Declarations (Check_Prag); + if Nkind (Decl) = N_Pragma then + if Pragma_Name (Decl) = Post_Nam then + if not Analyzed (Decl) then + Analyze (Decl); + end if; + + Check_Prag := Build_Pragma_Check_Equivalent (Decl); + + if Expander_Active then + Append_Enabled_Item + (Item => Check_Prag, + List => Stmts); + + -- When analyzing a generic unit, save the pragma for + -- later. + + else + Prepend_To_Declarations (Check_Prag); + end if; end if; + + -- Skip internally generated code + + elsif not Comes_From_Source (Decl) then + null; + + -- Postcondition pragmas are usually grouped together. There + -- is no need to inspect the whole declarative list. + + else + exit; end if; - -- Skip internally generated code + Next (Decl); + end loop; + end Collect_Body_Postconditions_In_Decls; - elsif not Comes_From_Source (Decl) then - null; + -- Local variables - -- Postconditions in bodies are usually grouped at the top of - -- the declarations. There is no point in inspecting the whole - -- source list. + Unit_Decl : constant Node_Id := Parent (N); - else - exit; - end if; + -- Start of processing for Collect_Body_Postconditions_Of_Kind - Next (Decl); - end loop; + begin + pragma Assert (Nam_In (Post_Nam, Name_Postcondition, + Name_Refined_Post)); + + -- Inspect the declarations of the subprogram body looking for a + -- pragma that matches the desired name. + + Collect_Body_Postconditions_In_Decls + (First_Decl => First (Declarations (N))); + + -- The subprogram body being processed is actually the proper body + -- of a stub with a corresponding spec. The subprogram stub may + -- carry a postcondition pragma in which case it must be taken + -- into account. The pragma appears after the stub. + + if Present (Spec_Id) and then Nkind (Unit_Decl) = N_Subunit then + Collect_Body_Postconditions_In_Decls + (First_Decl => Next (Corresponding_Stub (Unit_Decl))); + end if; end Collect_Body_Postconditions_Of_Kind; -- Start of processing for Collect_Body_Postconditions @@ -8808,11 +8850,45 @@ package body Exp_Ch6 is -------------------------------- procedure Collect_Spec_Preconditions (Subp_Id : Entity_Id) is + Class_Pre : Node_Id := Empty; + -- The sole class-wide precondition pragma that applies to the + -- subprogram. + + procedure Add_Or_Save_Precondition (Prag : Node_Id); + -- Save a class-wide precondition or add a regulat precondition to + -- the declarative list of the body. + procedure Merge_Preconditions (From : Node_Id; Into : Node_Id); -- Merge two class-wide preconditions by "or else"-ing them. The -- changes are accumulated in parameter Into. Update the error -- message of Into. + ------------------------------ + -- Add_Or_Save_Precondition -- + ------------------------------ + + procedure Add_Or_Save_Precondition (Prag : Node_Id) is + Check_Prag : Node_Id; + + begin + Check_Prag := Build_Pragma_Check_Equivalent (Prag); + + -- Save the sole class-wide precondition (if any) for the next + -- step where it will be merged with inherited preconditions. + + if Class_Present (Prag) then + pragma Assert (No (Class_Pre)); + Class_Pre := Check_Prag; + + -- Accumulate the corresponding Check pragmas to the top of the + -- declarations. Prepending the items ensures that they will be + -- evaluated in their original order. + + else + Prepend_To_Declarations (Check_Prag); + end if; + end Add_Or_Save_Precondition; + ------------------------- -- Merge_Preconditions -- ------------------------- @@ -8889,8 +8965,9 @@ package body Exp_Ch6 is Inher_Subps : constant Subprogram_List := Inherited_Subprograms (Subp_Id); + Subp_Decl : constant Node_Id := Parent (Parent (Subp_Id)); Check_Prag : Node_Id; - Class_Pre : Node_Id := Empty; + Decl : Node_Id; Inher_Subp_Id : Entity_Id; Prag : Node_Id; @@ -8902,25 +8979,49 @@ package body Exp_Ch6 is Prag := Pre_Post_Conditions (Contract (Subp_Id)); while Present (Prag) loop if Pragma_Name (Prag) = Name_Precondition then - Check_Prag := Build_Pragma_Check_Equivalent (Prag); + Add_Or_Save_Precondition (Prag); + end if; - -- Save the sole class-wide precondition (if any) for the next - -- step where it will be merged with inherited preconditions. + Prag := Next_Pragma (Prag); + end loop; - if Class_Present (Prag) then - Class_Pre := Check_Prag; + -- The subprogram declaration being processed is actually a body + -- stub. The stub may carry a precondition pragma in which case it + -- must be taken into account. The pragma appears after the stub. - -- Accumulate the corresponding Check pragmas to the top of the - -- declarations. Prepending the items ensures that they will - -- be evaluated in their original order. + if Nkind (Subp_Decl) = N_Subprogram_Body_Stub then + + -- Inspect the declarations following the body stub + + Decl := Next (Subp_Decl); + while Present (Decl) loop + + -- Note that non-matching pragmas are skipped + + if Nkind (Decl) = N_Pragma then + if Pragma_Name (Decl) = Name_Precondition then + if not Analyzed (Decl) then + Analyze (Decl); + end if; + + Add_Or_Save_Precondition (Decl); + end if; + + -- Skip internally generated code + + elsif not Comes_From_Source (Decl) then + null; + + -- Preconditions are usually grouped together. There is no need + -- to inspect the whole declarative list. else - Prepend_To_Declarations (Check_Prag); + exit; end if; - end if; - Prag := Next_Pragma (Prag); - end loop; + Next (Decl); + end loop; + end if; -- Process the contracts of all inherited subprograms, looking for -- class-wide preconditions. diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb index 7714526ae99..df4aacf6fc6 100644 --- a/gcc/ada/sem_ch10.adb +++ b/gcc/ada/sem_ch10.adb @@ -53,7 +53,6 @@ with Sem_Ch3; use Sem_Ch3; with Sem_Ch6; use Sem_Ch6; with Sem_Ch7; use Sem_Ch7; with Sem_Ch8; use Sem_Ch8; -with Sem_Ch13; use Sem_Ch13; with Sem_Dist; use Sem_Dist; with Sem_Prag; use Sem_Prag; with Sem_Util; use Sem_Util; @@ -1558,7 +1557,6 @@ package body Sem_Ch10 is procedure Analyze_Proper_Body (N : Node_Id; Nam : Entity_Id) is Subunit_Name : constant Unit_Name_Type := Get_Unit_Name (N); - Unum : Unit_Number_Type; procedure Optional_Subunit; -- This procedure is called when the main unit is a stub, or when we @@ -1573,6 +1571,7 @@ package body Sem_Ch10 is procedure Optional_Subunit is Comp_Unit : Node_Id; + Unum : Unit_Number_Type; begin -- Try to load subunit, but ignore any errors that occur during the @@ -1633,7 +1632,8 @@ package body Sem_Ch10 is -- Local variables - Stub_Id : Entity_Id; + Comp_Unit : Node_Id; + Unum : Unit_Number_Type; -- Start of processing for Analyze_Proper_Body @@ -1787,86 +1787,45 @@ package body Sem_Ch10 is Write_Eol; end if; - declare - Comp_Unit : constant Node_Id := Cunit (Unum); - Prop_Body : Node_Id; - - begin - -- Check for child unit instead of subunit - - if Nkind (Unit (Comp_Unit)) /= N_Subunit then - Error_Msg_N - ("expected SEPARATE subunit, found child unit", - Cunit_Entity (Unum)); - - -- OK, we have a subunit - - else - Prop_Body := Proper_Body (Unit (Comp_Unit)); - - -- Set corresponding stub (even if errors) + Comp_Unit := Cunit (Unum); - Set_Corresponding_Stub (Unit (Comp_Unit), N); + -- Check for child unit instead of subunit - -- Collect SCO information for loaded subunit if we are - -- in the main unit. + if Nkind (Unit (Comp_Unit)) /= N_Subunit then + Error_Msg_N + ("expected SEPARATE subunit, found child unit", + Cunit_Entity (Unum)); - if Generate_SCO - and then - In_Extended_Main_Source_Unit - (Cunit_Entity (Current_Sem_Unit)) - then - SCO_Record (Unum); - end if; - - -- Propagate all aspect specifications associated with - -- the stub to the proper body. - - Move_Or_Merge_Aspects (From => N, To => Prop_Body); - - -- Move all source pragmas that follow the body stub and - -- apply to it to the declarations of the proper body. + -- OK, we have a subunit - if Nkind (N) = N_Subprogram_Body_Stub then - Relocate_Pragmas_To_Body (N, Target_Body => Prop_Body); - end if; - - -- Analyze the unit if semantics active - - if not Fatal_Error (Unum) or else Try_Semantics then - Analyze_Subunit (Comp_Unit); - end if; + else + Set_Corresponding_Stub (Unit (Comp_Unit), N); + Set_Library_Unit (N, Comp_Unit); - -- Set the library unit pointer in any case + -- We update the version. Although we are not technically + -- semantically dependent on the subunit, given our approach + -- of macro substitution of subunits, it makes sense to + -- include it in the version identification. - Set_Library_Unit (N, Comp_Unit); + Version_Update (Cunit (Main_Unit), Comp_Unit); - -- We update the version. Although we are not technically - -- semantically dependent on the subunit, given our - -- approach of macro substitution of subunits, it makes - -- sense to include it in the version identification. + -- Collect SCO information for loaded subunit if we are in + -- the main unit. - Version_Update (Cunit (Main_Unit), Comp_Unit); + if Generate_SCO + and then + In_Extended_Main_Source_Unit + (Cunit_Entity (Current_Sem_Unit)) + then + SCO_Record (Unum); end if; - end; - - -- The unit which should contain the proper subprogram body does - -- not exist. Analyze the aspect specifications of the stub (if - -- any). - - elsif Nkind (N) = N_Subprogram_Body_Stub - and then Has_Aspects (N) - then - Stub_Id := Defining_Unit_Name (Specification (N)); - - -- Restore the proper visibility of the stub and its formals - - Push_Scope (Stub_Id); - Install_Formals (Stub_Id); - Analyze_Aspect_Specifications (N, Stub_Id); + -- Analyze the unit if semantics active - Pop_Scope; + if not Fatal_Error (Unum) or else Try_Semantics then + Analyze_Subunit (Comp_Unit); + end if; + end if; end if; end if; @@ -1901,6 +1860,17 @@ package body Sem_Ch10 is Error_Msg_N ("missing specification for Protected body", N); else + -- Currently there are no language-defined aspects that can apply to + -- a protected body stub. Issue an error and remove the aspects to + -- prevent cascaded errors. + + if Has_Aspects (N) then + Error_Msg_N + ("aspects on protected bodies are not allowed", + First (Aspect_Specifications (N))); + Remove_Aspects (N); + end if; + Set_Scope (Defining_Entity (N), Current_Scope); Set_Has_Completion (Etype (Nam)); Set_Corresponding_Spec_Of_Stub (N, Nam); @@ -2351,7 +2321,19 @@ package body Sem_Ch10 is if No (Nam) or else not Is_Task_Type (Etype (Nam)) then Error_Msg_N ("missing specification for task body", N); + else + -- Currently there are no language-defined aspects that can apply to + -- a task body stub. Issue an error and remove the aspects to prevent + -- cascaded errors. + + if Has_Aspects (N) then + Error_Msg_N + ("aspects on task bodies are not allowed", + First (Aspect_Specifications (N))); + Remove_Aspects (N); + end if; + Set_Scope (Defining_Entity (N), Current_Scope); Generate_Reference (Nam, Defining_Identifier (N), 'b'); Set_Corresponding_Spec_Of_Stub (N, Nam); diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb index efa359fdb97..d8c71d778cb 100644 --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -1234,14 +1234,6 @@ package body Sem_Ch13 is else Insert_After (N, Prag); - - -- Analyze the pragma before analyzing the proper body of a stub. - -- This ensures that the pragma will appear on the proper contract - -- list (see N_Contract). - - if Nkind (N) = N_Subprogram_Body_Stub then - Analyze (Prag); - end if; end if; end Insert_Delayed_Pragma; diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index ff3cbf25c2d..2433b32392d 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -2485,8 +2485,17 @@ package body Sem_Ch6 is if Has_Aspect (Spec_Id, Asp_Id) then Error_Msg_Name_1 := Asp_Nam; - Error_Msg_Name_2 := Ref_Nam; - Error_Msg_N ("aspect % should be %", Asp); + + -- Subunits cannot carry aspects that apply to a subprogram + -- declaration. + + if Nkind (Parent (N)) = N_Subunit then + Error_Msg_N ("aspect % cannot apply to a subunit", Asp); + + else + Error_Msg_Name_2 := Ref_Nam; + Error_Msg_N ("aspect % should be %", Asp); + end if; -- Otherwise the aspect must appear in the spec, not in the body: @@ -2912,28 +2921,16 @@ package body Sem_Ch6 is end if; end if; - -- Language-defined aspects cannot appear in a subprogram body [stub] if - -- the subprogram has a separate spec. Certainly implementation-defined - -- aspects are allowed to appear (per Aspects_On_Body_Of_Stub_OK). + -- Language-defined aspects cannot appear on a subprogram body [stub] if + -- the subprogram has a spec. Certain implementation-defined aspects are + -- allowed to break this rule (see table Aspect_On_Body_Or_Stub_OK). if Has_Aspects (N) then if Present (Spec_Id) and then not Aspects_On_Body_Or_Stub_OK (N) - - -- Do not emit an error on a subprogram body stub that act as - -- its own spec. - - and then Nkind (Parent (Parent (Spec_Id))) /= N_Subprogram_Body_Stub then Diagnose_Misplaced_Aspect_Specifications; - -- Delay the analysis of aspect specifications that apply to a body - -- stub until the proper body is analyzed. If the corresponding body - -- is missing, the aspects are still analyzed in Analyze_Proper_Body. - - elsif Nkind (N) in N_Body_Stub then - null; - else Analyze_Aspect_Specifications (N, Body_Id); end if; diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index 2b095eabbf6..a5eaf1304bd 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -3601,40 +3601,42 @@ package body Sem_Prag is Body_Decl := Find_Related_Subprogram_Or_Body (N, Do_Checks => True); - if not Nkind_In (Body_Decl, N_Subprogram_Body, - N_Subprogram_Body_Stub) - then - Pragma_Misplaced; - return; - end if; - - Body_Id := Defining_Entity (Body_Decl); - - -- The body [stub] must not act as a spec, in other words it has to - -- be paired with a corresponding spec. + -- Extract the entities of the spec and body if Nkind (Body_Decl) = N_Subprogram_Body then + Body_Id := Defining_Entity (Body_Decl); Spec_Id := Corresponding_Spec (Body_Decl); - else + + elsif Nkind (Body_Decl) = N_Subprogram_Body_Stub then + Body_Id := Defining_Entity (Body_Decl); Spec_Id := Corresponding_Spec_Of_Stub (Body_Decl); + + else + Pragma_Misplaced; + return; end if; + -- The pragma must apply to the second declaration of a subprogram. + -- In other words, the body [stub] cannot acts as a spec. + if No (Spec_Id) then Error_Pragma ("pragma % cannot apply to a stand alone body"); return; + + -- Catch the case where the subprogram body is a subunit and acts as + -- the third declaration of the subprogram. + + elsif Nkind (Parent (Body_Decl)) = N_Subunit then + Error_Pragma ("pragma % cannot apply to a subunit"); + return; end if; - -- The pragma may only apply to the body [stub] of a subprogram + -- The pragma can only apply to the body [stub] of a subprogram -- declared in the visible part of a package. Retrieve the context of -- the subprogram declaration. Spec_Decl := Parent (Parent (Spec_Id)); - pragma Assert - (Nkind_In (Spec_Decl, N_Abstract_Subprogram_Declaration, - N_Generic_Subprogram_Declaration, - N_Subprogram_Declaration)); - if Nkind (Parent (Spec_Decl)) /= N_Package_Specification then Error_Pragma ("pragma % must apply to the body of a subprogram declared in a " @@ -12445,10 +12447,24 @@ package body Sem_Prag is Subp_Decl := Find_Related_Subprogram_Or_Body (N, Do_Checks => True); - if Nkind (Subp_Decl) /= N_Subprogram_Declaration - and then (Nkind (Subp_Decl) /= N_Subprogram_Body - or else not Acts_As_Spec (Subp_Decl)) + if Nkind (Subp_Decl) = N_Subprogram_Declaration then + null; + + -- Body acts as spec + + elsif Nkind (Subp_Decl) = N_Subprogram_Body + and then No (Corresponding_Spec (Subp_Decl)) + then + null; + + -- Body stub acts as spec + + elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub + and then No (Corresponding_Spec_Of_Stub (Subp_Decl)) then + null; + + else Pragma_Misplaced; return; end if; @@ -12969,10 +12985,24 @@ package body Sem_Prag is Subp_Decl := Find_Related_Subprogram_Or_Body (N, Do_Checks => True); - if Nkind (Subp_Decl) /= N_Subprogram_Declaration - and then (Nkind (Subp_Decl) /= N_Subprogram_Body - or else not Acts_As_Spec (Subp_Decl)) + if Nkind (Subp_Decl) = N_Subprogram_Declaration then + null; + + -- Body acts as spec + + elsif Nkind (Subp_Decl) = N_Subprogram_Body + and then No (Corresponding_Spec (Subp_Decl)) then + null; + + -- Body stub acts as spec + + elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub + and then No (Corresponding_Spec_Of_Stub (Subp_Decl)) + then + null; + + else Pragma_Misplaced; return; end if; @@ -14239,10 +14269,24 @@ package body Sem_Prag is Subp_Decl := Find_Related_Subprogram_Or_Body (N, Do_Checks => True); - if Nkind (Subp_Decl) /= N_Subprogram_Declaration - and then (Nkind (Subp_Decl) /= N_Subprogram_Body - or else not Acts_As_Spec (Subp_Decl)) + if Nkind (Subp_Decl) = N_Subprogram_Declaration then + null; + + -- Body acts as spec + + elsif Nkind (Subp_Decl) = N_Subprogram_Body + and then No (Corresponding_Spec (Subp_Decl)) then + null; + + -- Body stub acts as spec + + elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub + and then No (Corresponding_Spec_Of_Stub (Subp_Decl)) + then + null; + + else Pragma_Misplaced; return; end if; |