Commit e0201d82 by Yannick Moy Committed by Pierre-Marie de Rodat

[Ada] Fix ownership checking for pointers in SPARK

Checking of the readable status of sub-expressions occurring in the
target path of an assignment should occur before the right-hand-side is
moved or borrowed or observed.

There is no impact on compilation.

2019-07-09  Yannick Moy  <moy@adacore.com>

gcc/ada/

	* sem_spark.adb (Check_Expression): Change signature to take an
	Extended_Checking_Mode, for handling read permission checking of
	sub-expressions in an assignment.
	(Check_Parameter_Or_Global): Adapt to new behavior of
	Check_Expression for mode Assign.
	(Check_Safe_Pointers): Do not analyze generic bodies.
	(Check_Assignment): Separate checking of the target of an
	assignment.

From-SVN: r273266
parent b5d3d113
2019-07-09 Yannick Moy <moy@adacore.com>
* sem_spark.adb (Check_Expression): Change signature to take an
Extended_Checking_Mode, for handling read permission checking of
sub-expressions in an assignment.
(Check_Parameter_Or_Global): Adapt to new behavior of
Check_Expression for mode Assign.
(Check_Safe_Pointers): Do not analyze generic bodies.
(Check_Assignment): Separate checking of the target of an
assignment.
2019-07-09 Eric Botcazou <ebotcazou@adacore.com> 2019-07-09 Eric Botcazou <ebotcazou@adacore.com>
* repinfo.ads (JSON format): Adjust. * repinfo.ads (JSON format): Adjust.
......
...@@ -560,9 +560,13 @@ package body Sem_SPARK is ...@@ -560,9 +560,13 @@ package body Sem_SPARK is
-- has the right permission, and also updating permissions when a path is -- has the right permission, and also updating permissions when a path is
-- moved, borrowed, or observed. -- moved, borrowed, or observed.
type Checking_Mode is type Extended_Checking_Mode is
(Read, (Read_Subexpr,
-- Special value used for assignment, to check that subexpressions of
-- the assigned path are readable.
Read,
-- Default mode -- Default mode
Move, Move,
...@@ -591,6 +595,8 @@ package body Sem_SPARK is ...@@ -591,6 +595,8 @@ package body Sem_SPARK is
-- and extensions are set to Read_Only. -- and extensions are set to Read_Only.
); );
subtype Checking_Mode is Extended_Checking_Mode range Read .. Observe;
type Result_Kind is (Folded, Unfolded); type Result_Kind is (Folded, Unfolded);
-- The type declaration to discriminate in the Perm_Or_Tree type -- The type declaration to discriminate in the Perm_Or_Tree type
...@@ -631,7 +637,7 @@ package body Sem_SPARK is ...@@ -631,7 +637,7 @@ package body Sem_SPARK is
procedure Check_Declaration (Decl : Node_Id); procedure Check_Declaration (Decl : Node_Id);
procedure Check_Expression (Expr : Node_Id; Mode : Checking_Mode); procedure Check_Expression (Expr : Node_Id; Mode : Extended_Checking_Mode);
pragma Precondition (Nkind_In (Expr, N_Index_Or_Discriminant_Constraint, pragma Precondition (Nkind_In (Expr, N_Index_Or_Discriminant_Constraint,
N_Range_Constraint, N_Range_Constraint,
N_Subtype_Indication) N_Subtype_Indication)
...@@ -1421,8 +1427,10 @@ package body Sem_SPARK is ...@@ -1421,8 +1427,10 @@ package body Sem_SPARK is
-- Check_Expression -- -- Check_Expression --
---------------------- ----------------------
procedure Check_Expression (Expr : Node_Id; Mode : Checking_Mode) is procedure Check_Expression
(Expr : Node_Id;
Mode : Extended_Checking_Mode)
is
-- Local subprograms -- Local subprograms
function Is_Type_Name (Expr : Node_Id) return Boolean; function Is_Type_Name (Expr : Node_Id) return Boolean;
...@@ -1543,8 +1551,14 @@ package body Sem_SPARK is ...@@ -1543,8 +1551,14 @@ package body Sem_SPARK is
return; return;
elsif Is_Path_Expression (Expr) then elsif Is_Path_Expression (Expr) then
Read_Indexes (Expr); if Mode /= Assign then
Process_Path (Expr, Mode); Read_Indexes (Expr);
end if;
if Mode /= Read_Subexpr then
Process_Path (Expr, Mode);
end if;
return; return;
end if; end if;
...@@ -2511,6 +2525,10 @@ package body Sem_SPARK is ...@@ -2511,6 +2525,10 @@ package body Sem_SPARK is
Mode := Move; Mode := Move;
end case; end case;
if Mode = Assign then
Check_Expression (Expr, Read_Subexpr);
end if;
Check_Expression (Expr, Mode); Check_Expression (Expr, Mode);
end Check_Parameter_Or_Global; end Check_Parameter_Or_Global;
...@@ -2618,11 +2636,6 @@ package body Sem_SPARK is ...@@ -2618,11 +2636,6 @@ package body Sem_SPARK is
Reset (Current_Perm_Env); Reset (Current_Perm_Env);
end Initialize; end Initialize;
-- Local variables
Prag : Node_Id;
-- SPARK_Mode pragma in application
-- Start of processing for Check_Safe_Pointers -- Start of processing for Check_Safe_Pointers
begin begin
...@@ -2636,20 +2649,28 @@ package body Sem_SPARK is ...@@ -2636,20 +2649,28 @@ package body Sem_SPARK is
| N_Package_Declaration | N_Package_Declaration
| N_Subprogram_Body | N_Subprogram_Body
=> =>
Prag := SPARK_Pragma (Defining_Entity (N)); declare
E : constant Entity_Id := Defining_Entity (N);
Prag : constant Node_Id := SPARK_Pragma (E);
-- SPARK_Mode pragma in application
if Present (Prag) then begin
if Get_SPARK_Mode_From_Annotation (Prag) = Opt.On then if Ekind (Unique_Entity (E)) in Generic_Unit_Kind then
Check_Node (N); null;
end if;
elsif Nkind (N) = N_Package_Body then elsif Present (Prag) then
Check_List (Declarations (N)); if Get_SPARK_Mode_From_Annotation (Prag) = Opt.On then
Check_Node (N);
end if;
elsif Nkind (N) = N_Package_Declaration then elsif Nkind (N) = N_Package_Body then
Check_List (Private_Declarations (Specification (N))); Check_List (Declarations (N));
Check_List (Visible_Declarations (Specification (N)));
end if; elsif Nkind (N) = N_Package_Declaration then
Check_List (Private_Declarations (Specification (N)));
Check_List (Visible_Declarations (Specification (N)));
end if;
end;
when others => when others =>
null; null;
...@@ -2717,7 +2738,14 @@ package body Sem_SPARK is ...@@ -2717,7 +2738,14 @@ package body Sem_SPARK is
when N_Assignment_Statement => when N_Assignment_Statement =>
declare declare
Target : constant Node_Id := Name (Stmt); Target : constant Node_Id := Name (Stmt);
begin begin
-- Start with checking that the subexpressions of the target
-- path are readable, before possibly updating the permission
-- of these subexpressions in Check_Assignment.
Check_Expression (Target, Read_Subexpr);
Check_Assignment (Target => Target, Check_Assignment (Target => Target,
Expr => Expression (Stmt)); Expr => Expression (Stmt));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment