aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorViljar Indus <indus@adacore.com>2025-08-25 10:13:02 +0300
committerMarc Poulhiès <dkm@gcc.gnu.org>2025-09-11 11:10:49 +0200
commit28b38b266d312e85ceae7f1b605eaa5b6583561d (patch)
tree9b88c6c86dfd01f35490a71a099cbd4e41a2b200
parent48f8e3027979088cacce27e0b552a59855940d87 (diff)
downloadgcc-28b38b266d312e85ceae7f1b605eaa5b6583561d.zip
gcc-28b38b266d312e85ceae7f1b605eaa5b6583561d.tar.gz
gcc-28b38b266d312e85ceae7f1b605eaa5b6583561d.tar.bz2
ada: Check ghost level dependencies inside assignments
Check that entities on the RHS are ghost level dependent on the entities on the LHS of the assignemnt. gcc/ada/ChangeLog: * ghost.adb (Is_OK_Statement): Check the levels of the assignee with the levels of the entity are ghost level dependent. (Check_Assignement_Levels): New function for checking the level dependencies.
-rw-r--r--gcc/ada/ghost.adb39
1 files changed, 39 insertions, 0 deletions
diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb
index bc646b2..0fbcf20 100644
--- a/gcc/ada/ghost.adb
+++ b/gcc/ada/ghost.adb
@@ -515,6 +515,10 @@ package body Ghost is
function Is_OK_Statement
(Stmt : Node_Id; Id : Entity_Id; Call_Arg : Node_Id) return Boolean
is
+ procedure Check_Assignment_Levels (Assignee : Entity_Id);
+ -- Check that a ghost entity on the RHS of the assignment is
+ -- assertion level dependent on the LHS.
+
procedure Check_Procedure_Call_Policies (Callee : Entity_Id);
-- Check that
-- * the a checked call argument is not modified by an ignored
@@ -528,6 +532,39 @@ package body Ghost is
-- Check that Call_Arg was used in the call and that the formal
-- for that argument was either out or in-out.
+ -----------------------------
+ -- Check_Assignment_Levels --
+ -----------------------------
+
+ procedure Check_Assignment_Levels (Assignee : Entity_Id) is
+ Assignee_Level : constant Entity_Id :=
+ Ghost_Assertion_Level (Assignee);
+ Id_Level : constant Entity_Id :=
+ Ghost_Assertion_Level (Id);
+ begin
+ -- SPARK RM 6.9 (13) A ghost entity E shall only be referenced
+ -- within an assignment statement whose target is a ghost
+ -- variable that is assertion-level-dependent on E.
+
+ if not Is_Assertion_Level_Dependent (Id_Level, Assignee_Level)
+ then
+ Error_Msg_Sloc := Sloc (Ghost_Ref);
+
+ Error_Msg_N (Assertion_Level_Error_Msg, Ghost_Ref);
+ Error_Msg_Name_1 := Chars (Id_Level);
+ Error_Msg_NE ("\& has assertion level %", Ghost_Ref, Id);
+ Error_Msg_Name_1 := Chars (Assignee_Level);
+ Error_Msg_Node_2 := Assignee;
+ Error_Msg_NE
+ ("\& is modifying & with %", Ghost_Ref, Id);
+ Error_Msg_Name_1 := Chars (Assignee_Level);
+ Error_Msg_NE
+ ("\assertion level of & should depend on %",
+ Ghost_Ref,
+ Id);
+ end if;
+ end Check_Assignment_Levels;
+
-----------------------------------
-- Check_Procedure_Call_Policies --
-----------------------------------
@@ -619,6 +656,8 @@ package body Ghost is
if Nkind (Stmt) = N_Assignment_Statement then
if Is_Ghost_Assignment (Stmt) then
+ Check_Assignment_Levels
+ (Get_Enclosing_Ghost_Entity (Name (Stmt)));
return True;
end if;