This patch modifies the processing of aspect/pragma SPARK_Mode to properly handle the cases where the aspect/pragma apply to a [library-level] package or subprogram [body].
------------ -- Source -- ------------ -- func.ads function Func return Integer with SPARK_Mode => On; -- pack.adb package body Pack with SPARK_Mode => Off is procedure Dummy is begin null; end Dummy; end Pack; -- pack.ads package Pack is procedure Dummy; end Pack; -- proc.ads procedure Proc with SPARK_Mode => On; -- spec.ads package Spec with SPARK_Mode => On is end Spec; ----------------- -- Compilation -- ----------------- $ gcc -c -gnatc -gnat12 -gnatd.V func.ads $ gcc -c -gnat12 -gnatd.V pack.adb $ gcc -c -gnatc -gnat12 -gnatd.V proc.ads $ gcc -c -gnatc -gnat12 -gnatd.V spec.ads Tested on x86_64-pc-linux-gnu, committed on trunk 2013-09-10 Hristian Kirtchev <kirtc...@adacore.com> * sem_prag.adb (Analyze_Pragma): Add processing for aspect/pragma SPARK_Mode when it applies to a [library-level] subprogram or package [body].
Index: sem_prag.adb =================================================================== --- sem_prag.adb (revision 202457) +++ sem_prag.adb (working copy) @@ -16633,12 +16633,53 @@ Stmt := Prev (Stmt); end loop; - -- If we get here, then we ran out of preceding statements. The - -- pragma is immediately within a body. + -- Handle all cases where the pragma is actually an aspect and + -- applies to a library-level package spec, body or subprogram. - if Nkind_In (Context, N_Package_Body, - N_Subprogram_Body) + -- function F ... with SPARK_Mode => ...; + -- package P with SPARK_Mode => ...; + -- package body P with SPARK_Mode => ... is + + -- The following circuitry simply prepares the proper context + -- for the general pragma processing mechanism below. + + if Nkind (Context) = N_Compilation_Unit_Aux then + Context := Unit (Parent (Context)); + + if Nkind_In (Context, N_Package_Declaration, + N_Subprogram_Declaration) + then + Context := Specification (Context); + end if; + end if; + + -- The pragma is at the top level of a package spec or appears + -- as an aspect on a subprogram. + + -- function F ... with SPARK_Mode => ...; + + -- package P is + -- pragma SPARK_Mode; + + if Nkind_In (Context, N_Function_Specification, + N_Package_Specification, + N_Procedure_Specification) then + Spec_Id := Defining_Unit_Name (Context); + Chain_Pragma (Spec_Id, N); + + -- The pragma is immediately within a package or subprogram + -- body. + + -- function F ... is + -- pragma SPARK_Mode; + + -- package body P is + -- pragma SPARK_Mode; + + elsif Nkind_In (Context, N_Package_Body, + N_Subprogram_Body) + then Spec_Id := Corresponding_Spec (Context); if Nkind (Context) = N_Subprogram_Body then @@ -16650,14 +16691,12 @@ Chain_Pragma (Body_Id, N); Check_Conformance (Spec_Id, Body_Id); - -- The pragma is at the top level of a package spec + -- The pragma applies to the statements of a package body - elsif Nkind (Context) = N_Package_Specification then - Spec_Id := Defining_Unit_Name (Context); - Chain_Pragma (Spec_Id, N); + -- package body P is + -- begin + -- pragma SPARK_Mode; - -- The pragma applies to the statements of a package body - elsif Nkind (Context) = N_Handled_Sequence_Of_Statements and then Nkind (Parent (Context)) = N_Package_Body then