Commit 1bc68e0d by Claire Dross Committed by Pierre-Marie de Rodat

[Ada] Fix possible crashes in GNATprove analysis of pointers

The new analysis of SPARK pointer rules could crash on some constructs.
Now fixed.

There is no impact on compilation.

2019-07-10  Claire Dross  <dross@adacore.com>

gcc/ada/

	* sem_spark.adb (Check_Expression): Allow digits constraints as
	input.
	(Illegal_Global_Usage): Pass in the entity.
	(Is_Subpath_Expression): New function to allow different nodes
	as inner parts of a path expression.
	(Read_Indexes): Allow concatenation and aggregates with box
	expressions.  Allow attributes Update and Loop_Entry.
	(Check_Expression): Allow richer membership test.
	(Check_Node): Ignore bodies of generics.
	(Get_Root_Object): Allow concatenation and attributes.

From-SVN: r273348
parent d036b2b8
2019-07-10 Claire Dross <dross@adacore.com>
* sem_spark.adb (Check_Expression): Allow digits constraints as
input.
(Illegal_Global_Usage): Pass in the entity.
(Is_Subpath_Expression): New function to allow different nodes
as inner parts of a path expression.
(Read_Indexes): Allow concatenation and aggregates with box
expressions. Allow attributes Update and Loop_Entry.
(Check_Expression): Allow richer membership test.
(Check_Node): Ignore bodies of generics.
(Get_Root_Object): Allow concatenation and attributes.
2019-07-10 Hristian Kirtchev <kirtchev@adacore.com> 2019-07-10 Hristian Kirtchev <kirtchev@adacore.com>
* sem_ch6.adb (Check_Discriminant_Conformance): Use Find_Type to * sem_ch6.adb (Check_Discriminant_Conformance): Use Find_Type to
......
...@@ -640,7 +640,8 @@ package body Sem_SPARK is ...@@ -640,7 +640,8 @@ package body Sem_SPARK is
procedure Check_Expression (Expr : Node_Id; Mode : Extended_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,
N_Digits_Constraint)
or else Nkind (Expr) in N_Subexpr); or else Nkind (Expr) in N_Subexpr);
procedure Check_Globals (Subp : Entity_Id); procedure Check_Globals (Subp : Entity_Id);
...@@ -738,7 +739,7 @@ package body Sem_SPARK is ...@@ -738,7 +739,7 @@ package body Sem_SPARK is
-- the debugger to look into a hash table. -- the debugger to look into a hash table.
pragma Unreferenced (Hp); pragma Unreferenced (Hp);
procedure Illegal_Global_Usage (N : Node_Or_Entity_Id); procedure Illegal_Global_Usage (N : Node_Or_Entity_Id; E : Entity_Id);
pragma No_Return (Illegal_Global_Usage); pragma No_Return (Illegal_Global_Usage);
-- A procedure that is called when deep globals or aliased globals are used -- A procedure that is called when deep globals or aliased globals are used
-- without any global aspect. -- without any global aspect.
...@@ -750,6 +751,9 @@ package body Sem_SPARK is ...@@ -750,6 +751,9 @@ package body Sem_SPARK is
function Is_Path_Expression (Expr : Node_Id) return Boolean; function Is_Path_Expression (Expr : Node_Id) return Boolean;
-- Return whether Expr corresponds to a path -- Return whether Expr corresponds to a path
function Is_Subpath_Expression (Expr : Node_Id) return Boolean;
-- Return True if Expr can be part of a path expression
function Is_Prefix_Or_Almost (Pref, Expr : Node_Id) return Boolean; function Is_Prefix_Or_Almost (Pref, Expr : Node_Id) return Boolean;
-- Determine if the candidate Prefix is indeed a prefix of Expr, or almost -- Determine if the candidate Prefix is indeed a prefix of Expr, or almost
-- a prefix, in the sense that they could still refer to overlapping memory -- a prefix, in the sense that they could still refer to overlapping memory
...@@ -1302,7 +1306,9 @@ package body Sem_SPARK is ...@@ -1302,7 +1306,9 @@ package body Sem_SPARK is
begin begin
-- Only SPARK bodies are analyzed -- Only SPARK bodies are analyzed
if No (Prag) or else Get_SPARK_Mode_From_Annotation (Prag) /= Opt.On then if No (Prag)
or else Get_SPARK_Mode_From_Annotation (Prag) /= Opt.On
then
return; return;
end if; end if;
...@@ -1312,9 +1318,8 @@ package body Sem_SPARK is ...@@ -1312,9 +1318,8 @@ package body Sem_SPARK is
and then Is_Anonymous_Access_Type (Etype (Spec_Id)) and then Is_Anonymous_Access_Type (Etype (Spec_Id))
and then not Is_Traversal_Function (Spec_Id) and then not Is_Traversal_Function (Spec_Id)
then then
Error_Msg_N Error_Msg_N ("anonymous access type for result only allowed for "
("anonymous access type for result only allowed for traveral " & "traveral functions", Spec_Id);
& "functions", Spec_Id);
return; return;
end if; end if;
...@@ -1568,7 +1573,7 @@ package body Sem_SPARK is ...@@ -1568,7 +1573,7 @@ package body Sem_SPARK is
-- Start of processing for Read_Indexes -- Start of processing for Read_Indexes
begin begin
if not Is_Path_Expression (Expr) then if not Is_Subpath_Expression (Expr) then
Error_Msg_N ("name expected here for move/borrow/observe", Expr); Error_Msg_N ("name expected here for move/borrow/observe", Expr);
return; return;
end if; end if;
...@@ -1603,6 +1608,10 @@ package body Sem_SPARK is ...@@ -1603,6 +1608,10 @@ package body Sem_SPARK is
Read_Params (Expr); Read_Params (Expr);
Check_Globals (Get_Called_Entity (Expr)); Check_Globals (Get_Called_Entity (Expr));
when N_Op_Concat =>
Read_Expression (Left_Opnd (Expr));
Read_Expression (Right_Opnd (Expr));
when N_Qualified_Expression when N_Qualified_Expression
| N_Type_Conversion | N_Type_Conversion
| N_Unchecked_Type_Conversion | N_Unchecked_Type_Conversion
...@@ -1644,7 +1653,8 @@ package body Sem_SPARK is ...@@ -1644,7 +1653,8 @@ package body Sem_SPARK is
-- There can be only one element for a value of deep type -- There can be only one element for a value of deep type
-- in order to avoid aliasing. -- in order to avoid aliasing.
if Is_Deep (Etype (Expression (Assoc))) if not (Box_Present (Assoc))
and then Is_Deep (Etype (Expression (Assoc)))
and then not Is_Singleton_Choice (CL) and then not Is_Singleton_Choice (CL)
then then
Error_Msg_F Error_Msg_F
...@@ -1655,7 +1665,9 @@ package body Sem_SPARK is ...@@ -1655,7 +1665,9 @@ package body Sem_SPARK is
-- The subexpressions of an aggregate are moved as part -- The subexpressions of an aggregate are moved as part
-- of the implicit assignments. -- of the implicit assignments.
Move_Expression (Expression (Assoc)); if not Box_Present (Assoc) then
Move_Expression (Expression (Assoc));
end if;
Next (Assoc); Next (Assoc);
end loop; end loop;
...@@ -1689,12 +1701,28 @@ package body Sem_SPARK is ...@@ -1689,12 +1701,28 @@ package body Sem_SPARK is
-- The subexpressions of an aggregate are moved as part -- The subexpressions of an aggregate are moved as part
-- of the implicit assignments. -- of the implicit assignments.
Move_Expression (Expression (Assoc)); if not Box_Present (Assoc) then
Move_Expression (Expression (Assoc));
end if;
Next (Assoc); Next (Assoc);
end loop; end loop;
end; end;
when N_Attribute_Reference =>
pragma Assert
(Get_Attribute_Id (Attribute_Name (Expr)) =
Attribute_Loop_Entry
or else
Get_Attribute_Id (Attribute_Name (Expr)) = Attribute_Update);
Read_Expression (Prefix (Expr));
if Get_Attribute_Id (Attribute_Name (Expr)) = Attribute_Update
then
Read_Expression_List (Expressions (Expr));
end if;
when others => when others =>
raise Program_Error; raise Program_Error;
end case; end case;
...@@ -1758,6 +1786,13 @@ package body Sem_SPARK is ...@@ -1758,6 +1786,13 @@ package body Sem_SPARK is
end if; end if;
return; return;
when N_Digits_Constraint =>
Read_Expression (Digits_Expression (Expr));
if Present (Range_Constraint (Expr)) then
Read_Expression (Range_Constraint (Expr));
end if;
return;
when others => when others =>
null; null;
end case; end case;
...@@ -1767,12 +1802,28 @@ package body Sem_SPARK is ...@@ -1767,12 +1802,28 @@ package body Sem_SPARK is
case N_Subexpr'(Nkind (Expr)) is case N_Subexpr'(Nkind (Expr)) is
when N_Binary_Op when N_Binary_Op
| N_Membership_Test
| N_Short_Circuit | N_Short_Circuit
=> =>
Read_Expression (Left_Opnd (Expr)); Read_Expression (Left_Opnd (Expr));
Read_Expression (Right_Opnd (Expr)); Read_Expression (Right_Opnd (Expr));
when N_Membership_Test =>
Read_Expression (Left_Opnd (Expr));
if Present (Right_Opnd (Expr)) then
Read_Expression (Right_Opnd (Expr));
else
declare
Cases : constant List_Id := Alternatives (Expr);
Cur_Case : Node_Id := First (Cases);
begin
while Present (Cur_Case) loop
Read_Expression (Cur_Case);
Next (Cur_Case);
end loop;
end;
end if;
when N_Unary_Op => when N_Unary_Op =>
Read_Expression (Right_Opnd (Expr)); Read_Expression (Right_Opnd (Expr));
...@@ -1856,6 +1907,14 @@ package body Sem_SPARK is ...@@ -1856,6 +1907,14 @@ package body Sem_SPARK is
when Attribute_Modulus => when Attribute_Modulus =>
null; null;
-- The following attributes apply to types; there are no
-- expressions to read.
when Attribute_Class
| Attribute_Storage_Size
=>
null;
-- Postconditions should not be analyzed -- Postconditions should not be analyzed
when Attribute_Old when Attribute_Old
...@@ -2418,13 +2477,17 @@ package body Sem_SPARK is ...@@ -2418,13 +2477,17 @@ package body Sem_SPARK is
Check_Call_Statement (N); Check_Call_Statement (N);
when N_Package_Body => when N_Package_Body =>
Check_Package_Body (N); if not Is_Generic_Unit (Unique_Defining_Entity (N)) then
Check_Package_Body (N);
end if;
when N_Subprogram_Body when N_Subprogram_Body
| N_Entry_Body | N_Entry_Body
| N_Task_Body | N_Task_Body
=> =>
Check_Callable_Body (N); if not Is_Generic_Unit (Unique_Defining_Entity (N)) then
Check_Callable_Body (N);
end if;
when N_Protected_Body => when N_Protected_Body =>
Check_List (Declarations (N)); Check_List (Declarations (N));
...@@ -3399,7 +3462,7 @@ package body Sem_SPARK is ...@@ -3399,7 +3462,7 @@ package body Sem_SPARK is
if not Inside_Elaboration if not Inside_Elaboration
and then C = null and then C = null
then then
Illegal_Global_Usage (N); Illegal_Global_Usage (N, N);
end if; end if;
return (R => Unfolded, Tree_Access => C); return (R => Unfolded, Tree_Access => C);
...@@ -3498,7 +3561,7 @@ package body Sem_SPARK is ...@@ -3498,7 +3561,7 @@ package body Sem_SPARK is
Through_Traversal : Boolean := True) return Entity_Id Through_Traversal : Boolean := True) return Entity_Id
is is
begin begin
if not Is_Path_Expression (Expr) then if not Is_Subpath_Expression (Expr) then
Error_Msg_N ("name expected here for path", Expr); Error_Msg_N ("name expected here for path", Expr);
return Empty; return Empty;
end if; end if;
...@@ -3517,12 +3580,13 @@ package body Sem_SPARK is ...@@ -3517,12 +3580,13 @@ package body Sem_SPARK is
return Get_Root_Object (Prefix (Expr), Through_Traversal); return Get_Root_Object (Prefix (Expr), Through_Traversal);
-- There is no root object for an (extension) aggregate, allocator, -- There is no root object for an (extension) aggregate, allocator,
-- or NULL. -- concat, or NULL.
when N_Aggregate when N_Aggregate
| N_Allocator | N_Allocator
| N_Extension_Aggregate | N_Extension_Aggregate
| N_Null | N_Null
| N_Op_Concat
=> =>
return Empty; return Empty;
...@@ -3545,6 +3609,15 @@ package body Sem_SPARK is ...@@ -3545,6 +3609,15 @@ package body Sem_SPARK is
=> =>
return Get_Root_Object (Expression (Expr), Through_Traversal); return Get_Root_Object (Expression (Expr), Through_Traversal);
when N_Attribute_Reference =>
pragma Assert
(Get_Attribute_Id (Attribute_Name (Expr)) =
Attribute_Loop_Entry
or else
Get_Attribute_Id (Attribute_Name (Expr)) =
Attribute_Update);
return Empty;
when others => when others =>
raise Program_Error; raise Program_Error;
end case; end case;
...@@ -3646,9 +3719,10 @@ package body Sem_SPARK is ...@@ -3646,9 +3719,10 @@ package body Sem_SPARK is
-- Illegal_Global_Usage -- -- Illegal_Global_Usage --
-------------------------- --------------------------
procedure Illegal_Global_Usage (N : Node_Or_Entity_Id) is procedure Illegal_Global_Usage (N : Node_Or_Entity_Id; E : Entity_Id)
is
begin begin
Error_Msg_NE ("cannot use global variable & of deep type", N, N); Error_Msg_NE ("cannot use global variable & of deep type", N, E);
Error_Msg_N ("\without prior declaration in a Global aspect", N); Error_Msg_N ("\without prior declaration in a Global aspect", N);
Errout.Finalize (Last_Call => True); Errout.Finalize (Last_Call => True);
Errout.Output_Messages; Errout.Output_Messages;
...@@ -3668,7 +3742,7 @@ package body Sem_SPARK is ...@@ -3668,7 +3742,7 @@ package body Sem_SPARK is
when E_Array_Type when E_Array_Type
| E_Array_Subtype | E_Array_Subtype
=> =>
return Is_Deep (Component_Type (Typ)); return Is_Deep (Component_Type (Underlying_Type (Typ)));
when Record_Kind => when Record_Kind =>
declare declare
...@@ -3861,6 +3935,23 @@ package body Sem_SPARK is ...@@ -3861,6 +3935,23 @@ package body Sem_SPARK is
end Is_Prefix_Or_Almost; end Is_Prefix_Or_Almost;
--------------------------- ---------------------------
-- Is_Subpath_Expression --
---------------------------
function Is_Subpath_Expression (Expr : Node_Id) return Boolean is
begin
return Is_Path_Expression (Expr)
or else (Nkind (Expr) = N_Attribute_Reference
and then
(Get_Attribute_Id (Attribute_Name (Expr)) =
Attribute_Update
or else
Get_Attribute_Id (Attribute_Name (Expr)) =
Attribute_Loop_Entry))
or else Nkind (Expr) = N_Op_Concat;
end Is_Subpath_Expression;
---------------------------
-- Is_Traversal_Function -- -- Is_Traversal_Function --
--------------------------- ---------------------------
...@@ -4397,7 +4488,7 @@ package body Sem_SPARK is ...@@ -4397,7 +4488,7 @@ package body Sem_SPARK is
if not Inside_Elaboration if not Inside_Elaboration
and then Get (Current_Perm_Env, Root) = null and then Get (Current_Perm_Env, Root) = null
then then
Illegal_Global_Usage (Expr); Illegal_Global_Usage (Expr, Root);
end if; end if;
-- During elaboration, only the validity of operations is checked, no -- During elaboration, only the validity of operations is checked, no
......
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