From: Piotr Trojanek <troja...@adacore.com> Add check for references to subprogram outputs occurring within the Program_Exit expression. This check is necessarily partial, as it misses objects referenced by subprograms called from the Program_Exit expression, but this is consistent with other checks.
gcc/ada/ChangeLog: * sem_prag.adb (Analyze_Pragma): Add dependency of Program_Exit on Global and Depends contracts. (Analyze_Program_Exit_In_Decl_Part): Check references to subprogram outputs. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/sem_prag.adb | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index 70681231329..b94606eabc7 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -23717,6 +23717,8 @@ package body Sem_Prag is Analyze_If_Present (Pragma_SPARK_Mode); Analyze_If_Present (Pragma_Volatile_Function); + Analyze_If_Present (Pragma_Global); + Analyze_If_Present (Pragma_Depends); Analyze_Program_Exit_In_Decl_Part (N); end if; end Program_Exit; @@ -28425,6 +28427,46 @@ package body Sem_Prag is Errors : Nat; Restore_Scope : Boolean := False; + Unused : Boolean; + + Subp_Inputs, Subp_Outputs : Elist_Id := No_Elist; + -- Inputs and outputs of the subprogram + + function Check_Reference (N : Node_Id) return Traverse_Result; + -- Check references to objects within the Program_Exit expression + + --------------------- + -- Check_Reference -- + --------------------- + + function Check_Reference (N : Node_Id) return Traverse_Result is + begin + -- If an output of a subprogram with side effects is mentioned + -- in the boolean expression of its aspect Program_Exit, then it + -- shall either occur inside the prefix of a reference to the Old + -- attribute or be a stand-alone object. + + if Is_Attribute_Old (N) then + return Skip; + end if; + + if Is_Entity_Name (N) then + declare + E : constant Entity_Id := Entity (N); + begin + if Appears_In (Subp_Outputs, E) + and then Ekind (E) not in E_Constant | E_Variable + then + Error_Msg_NE + ("reference to subprogram output & in Program_Exit", N, E); + end if; + end; + end if; + + return OK; + end Check_Reference; + + procedure Check_Exit_References is new Traverse_Proc (Check_Reference); -- Start of processing for Analyze_Pre_Post_Condition_In_Decl_Part @@ -28475,6 +28517,15 @@ package body Sem_Prag is Preanalyze_And_Resolve_Assert_Expression (Expression (Arg1), Any_Boolean); + Collect_Subprogram_Inputs_Outputs + (Spec_Id, + Synthesize => True, + Subp_Inputs => Subp_Inputs, + Subp_Outputs => Subp_Outputs, + Global_Seen => Unused); + + Check_Exit_References (Expression (Arg1)); + -- Emit a clarification message when the expression contains at least -- one undefined reference, possibly due to contract freezing. -- 2.43.0