Commit dd91386d by Arnaud Charlet

[multiple changes]

2012-01-23  Robert Dewar  <dewar@adacore.com>

	* sem_prag.ads, sem_prag.adb: Minor reformatting.

2012-01-23  Robert Dewar  <dewar@adacore.com>

	* sem_ch13.adb (Analyze_Aspect_Specifications): Check for
	language defined aspect applied to renaming or formal type
	declaration (not permitted)

2012-01-23  Matthew Heaney  <heaney@adacore.com>

	* a-cdlili.adb, a-cidlli.adb, a-cbdlli.adb (Vet): Replaced
	comment with pragma Assert.

From-SVN: r183423
parent f6834394
2012-01-23 Robert Dewar <dewar@adacore.com>
* sem_prag.ads, sem_prag.adb: Minor reformatting.
2012-01-23 Robert Dewar <dewar@adacore.com>
* sem_ch13.adb (Analyze_Aspect_Specifications): Check for
language defined aspect applied to renaming or formal type
declaration (not permitted)
2012-01-23 Matthew Heaney <heaney@adacore.com>
* a-cdlili.adb, a-cidlli.adb, a-cbdlli.adb (Vet): Replaced
comment with pragma Assert.
2012-01-23 Vincent Pucci <pucci@adacore.com> 2012-01-23 Vincent Pucci <pucci@adacore.com>
* sem_ch12.adb (Analyze_Generic_Subprogram_Declaration): Call * sem_ch12.adb (Analyze_Generic_Subprogram_Declaration): Call
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 2004-2011, Free Software Foundation, Inc. -- -- Copyright (C) 2004-2012, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -81,6 +81,11 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is ...@@ -81,6 +81,11 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is
New_Node : Count_Type); New_Node : Count_Type);
function Vet (Position : Cursor) return Boolean; function Vet (Position : Cursor) return Boolean;
-- Checks invariants of the cursor and its designated container, as a
-- simple way of detecting dangling references (see operation Free for a
-- description of the detection mechanism), returning True if all checks
-- pass. Invocations of Vet are used here as the argument of pragma Assert,
-- so the checks are performed only when assertions are enabled.
--------- ---------
-- "=" -- -- "=" --
...@@ -682,7 +687,7 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is ...@@ -682,7 +687,7 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is
-- When an element is deleted from the list container, its node becomes -- When an element is deleted from the list container, its node becomes
-- inactive, and so we set its Prev component to a negative value, to -- inactive, and so we set its Prev component to a negative value, to
-- indicate that it is now inactive. This provides a useful way to -- indicate that it is now inactive. This provides a useful way to
-- detect a dangling cursor reference. -- detect a dangling cursor reference (and which is used in Vet).
N (X).Prev := -1; -- Node is deallocated (not on active list) N (X).Prev := -1; -- Node is deallocated (not on active list)
...@@ -2184,6 +2189,14 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is ...@@ -2184,6 +2189,14 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is
return False; return False;
end if; end if;
-- An invariant of an active node is that its Previous and Next
-- components are non-negative. Operation Free sets the Previous
-- component of the node to the value -1 before actually deallocating
-- the node, to mark the node as inactive. (By "dellocating" we mean
-- only that the node is linked onto a list of inactive nodes used
-- for storage.) This marker gives us a simple way to detect a
-- dangling reference to a node.
if N (Position.Node).Prev < 0 then -- see Free if N (Position.Node).Prev < 0 then -- see Free
return False; return False;
end if; end if;
...@@ -2206,9 +2219,8 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is ...@@ -2206,9 +2219,8 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is
return False; return False;
end if; end if;
-- If we get here, we know that this disjunction is true: pragma Assert (N (Position.Node).Prev /= 0
-- N (Position.Node).Prev /= 0 or else Position.Node = L.First or else Position.Node = L.First);
-- Why not do this with an assertion???
if N (Position.Node).Next = 0 if N (Position.Node).Next = 0
and then Position.Node /= L.Last and then Position.Node /= L.Last
...@@ -2216,9 +2228,8 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is ...@@ -2216,9 +2228,8 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is
return False; return False;
end if; end if;
-- If we get here, we know that this disjunction is true: pragma Assert (N (Position.Node).Next /= 0
-- N (Position.Node).Next /= 0 or else Position.Node = L.Last or else Position.Node = L.Last);
-- Why not do this with an assertion???
if L.Length = 1 then if L.Length = 1 then
return L.First = L.Last; return L.First = L.Last;
...@@ -2264,21 +2275,17 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is ...@@ -2264,21 +2275,17 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is
return False; return False;
end if; end if;
-- Eliminate earlier disjunct if Position.Node = L.First then -- eliminates earlier disjunct
if Position.Node = L.First then
return True; return True;
end if; end if;
-- If we get to this point, we know that this predicate is true: pragma Assert (N (Position.Node).Prev /= 0);
-- N (Position.Node).Prev /= 0
if Position.Node = L.Last then -- eliminates earlier disjunct if Position.Node = L.Last then -- eliminates earlier disjunct
return True; return True;
end if; end if;
-- If we get to this point, we know that this predicate is true: pragma Assert (N (Position.Node).Next /= 0);
-- N (Position.Node).Next /= 0
if N (N (Position.Node).Next).Prev /= Position.Node then if N (N (Position.Node).Next).Prev /= Position.Node then
return False; return False;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 2004-2011, Free Software Foundation, Inc. -- -- Copyright (C) 2004-2012, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -65,6 +65,11 @@ package body Ada.Containers.Doubly_Linked_Lists is ...@@ -65,6 +65,11 @@ package body Ada.Containers.Doubly_Linked_Lists is
New_Node : Node_Access); New_Node : Node_Access);
function Vet (Position : Cursor) return Boolean; function Vet (Position : Cursor) return Boolean;
-- Checks invariants of the cursor and its designated container, as a
-- simple way of detecting dangling references (see operation Free for a
-- description of the detection mechanism), returning True if all checks
-- pass. Invocations of Vet are used here as the argument of pragma Assert,
-- so the checks are performed only when assertions are enabled.
--------- ---------
-- "=" -- -- "=" --
...@@ -528,8 +533,23 @@ package body Ada.Containers.Doubly_Linked_Lists is ...@@ -528,8 +533,23 @@ package body Ada.Containers.Doubly_Linked_Lists is
procedure Deallocate is procedure Deallocate is
new Ada.Unchecked_Deallocation (Node_Type, Node_Access); new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
begin begin
-- While a node is in use, as an active link in a list, its Previous and
-- Next components must be null, or designate a different node; this is
-- a node invariant. Before actually deallocating the node, we set both
-- access value components of the node to point to the node itself, thus
-- falsifying the node invariant. Subprogram Vet inspects the value of
-- the node components when interrogating the node, in order to detect
-- whether the cursor's node access value is dangling.
-- Note that we have no guarantee that the storage for the node isn't
-- modified when it is deallocated, but there are other tests that Vet
-- does if node invariants appear to be satisifed. However, in practice
-- this simple test works well enough, detecting dangling references
-- immediately, without needing further interrogation.
X.Prev := X; X.Prev := X;
X.Next := X; X.Next := X;
Deallocate (X); Deallocate (X);
end Free; end Free;
...@@ -1966,6 +1986,13 @@ package body Ada.Containers.Doubly_Linked_Lists is ...@@ -1966,6 +1986,13 @@ package body Ada.Containers.Doubly_Linked_Lists is
return False; return False;
end if; end if;
-- An invariant of a node is that its Previous and Next components can
-- be null, or designate a different node. Operation Free sets the
-- access value components of the node to designate the node itself
-- before actually deallocating the node, thus deliberately violating
-- the node invariant. This gives us a simple way to detect a dangling
-- reference to a node.
if Position.Node.Next = Position.Node then if Position.Node.Next = Position.Node then
return False; return False;
end if; end if;
...@@ -1974,6 +2001,12 @@ package body Ada.Containers.Doubly_Linked_Lists is ...@@ -1974,6 +2001,12 @@ package body Ada.Containers.Doubly_Linked_Lists is
return False; return False;
end if; end if;
-- In practice the tests above will detect most instances of a dangling
-- reference. If we get here, it means that the invariants of the
-- designated node are satisfied (they at least appear to be satisfied),
-- so we perform some more tests, to determine whether invariants of the
-- designated list are satisfied too.
declare declare
L : List renames Position.Container.all; L : List renames Position.Container.all;
begin begin
...@@ -2003,8 +2036,8 @@ package body Ada.Containers.Doubly_Linked_Lists is ...@@ -2003,8 +2036,8 @@ package body Ada.Containers.Doubly_Linked_Lists is
return False; return False;
end if; end if;
-- If we get here, we know that this disjunction is true: pragma Assert (Position.Node.Prev /= null
-- Position.Node.Prev /= null or else Position.Node = L.First or else Position.Node = L.First);
if Position.Node.Next = null if Position.Node.Next = null
and then Position.Node /= L.Last and then Position.Node /= L.Last
...@@ -2012,8 +2045,8 @@ package body Ada.Containers.Doubly_Linked_Lists is ...@@ -2012,8 +2045,8 @@ package body Ada.Containers.Doubly_Linked_Lists is
return False; return False;
end if; end if;
-- If we get here, we know that this disjunction is true: pragma Assert (Position.Node.Next /= null
-- Position.Node.Next /= null or else Position.Node = L.Last or else Position.Node = L.Last);
if L.Length = 1 then if L.Length = 1 then
return L.First = L.Last; return L.First = L.Last;
...@@ -2059,23 +2092,17 @@ package body Ada.Containers.Doubly_Linked_Lists is ...@@ -2059,23 +2092,17 @@ package body Ada.Containers.Doubly_Linked_Lists is
return False; return False;
end if; end if;
-- Eliminate earlier disjunct if Position.Node = L.First then -- eliminates earlier disjunct
if Position.Node = L.First then
return True; return True;
end if; end if;
-- If we get here, we know (disjunctive syllogism) that this pragma Assert (Position.Node.Prev /= null);
-- predicate is true: Position.Node.Prev /= null
-- Eliminate earlier disjunct
if Position.Node = L.Last then if Position.Node = L.Last then -- eliminates earlier disjunct
return True; return True;
end if; end if;
-- If we get here, we know (disjunctive syllogism) that this pragma Assert (Position.Node.Next /= null);
-- predicate is true: Position.Node.Next /= null
if Position.Node.Next.Prev /= Position.Node then if Position.Node.Next.Prev /= Position.Node then
return False; return False;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 2004-2011, Free Software Foundation, Inc. -- -- Copyright (C) 2004-2012, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -68,6 +68,11 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is ...@@ -68,6 +68,11 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
New_Node : Node_Access); New_Node : Node_Access);
function Vet (Position : Cursor) return Boolean; function Vet (Position : Cursor) return Boolean;
-- Checks invariants of the cursor and its designated container, as a
-- simple way of detecting dangling references (see operation Free for a
-- description of the detection mechanism), returning True if all checks
-- pass. Invocations of Vet are used here as the argument of pragma Assert,
-- so the checks are performed only when assertions are enabled.
--------- ---------
-- "=" -- -- "=" --
...@@ -570,6 +575,23 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is ...@@ -570,6 +575,23 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
new Ada.Unchecked_Deallocation (Node_Type, Node_Access); new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
begin begin
-- While a node is in use, as an active link in a list, its Previous and
-- Next components must be null, or designate a different node; this is
-- a node invariant. For this indefinite list, there is an additional
-- invariant: that the element access value be non-null. Before actually
-- deallocating the node, we set the node access value components of the
-- node to point to the node itself, and set the element access value to
-- null (by deallocating the node's element), thus falsifying the node
-- invariant. Subprogram Vet inspects the value of the node components
-- when interrogating the node, in order to detect whether the cursor's
-- node access value is dangling.
-- Note that we have no guarantee that the storage for the node isn't
-- modified when it is deallocated, but there are other tests that Vet
-- does if node invariants appear to be satisifed. However, in practice
-- this simple test works well enough, detecting dangling references
-- immediately, without needing further interrogation.
X.Next := X; X.Next := X;
X.Prev := X; X.Prev := X;
...@@ -2048,6 +2070,14 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is ...@@ -2048,6 +2070,14 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
return False; return False;
end if; end if;
-- An invariant of a node is that its Previous and Next components can
-- be null, or designate a different node. Also, its element access
-- value must be non-null. Operation Free sets the node access value
-- components of the node to designate the node itself, and the element
-- access value to null, before actually deallocating the node, thus
-- deliberately violating the node invariant. This gives us a simple way
-- to detect a dangling reference to a node.
if Position.Node.Next = Position.Node then if Position.Node.Next = Position.Node then
return False; return False;
end if; end if;
...@@ -2060,6 +2090,12 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is ...@@ -2060,6 +2090,12 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
return False; return False;
end if; end if;
-- In practice the tests above will detect most instances of a dangling
-- reference. If we get here, it means that the invariants of the
-- designated node are satisfied (they at least appear to be satisfied),
-- so we perform some more tests, to determine whether invariants of the
-- designated list are satisfied too.
declare declare
L : List renames Position.Container.all; L : List renames Position.Container.all;
begin begin
......
...@@ -890,6 +890,28 @@ package body Sem_Ch13 is ...@@ -890,6 +890,28 @@ package body Sem_Ch13 is
end loop; end loop;
end if; end if;
-- Check some general restrictions on language defined aspects
if not Impl_Defined_Aspects (A_Id) then
Error_Msg_Name_1 := Nam;
-- Not allowed for renaming declarations
if Nkind (N) in N_Renaming_Declaration then
Error_Msg_N
("aspect % not allowed for renaming declaration",
Aspect);
end if;
-- Not allowed for formal type declarations
if Nkind (N) = N_Formal_Type_Declaration then
Error_Msg_N
("aspect % not allowed for formal type declaration",
Aspect);
end if;
end if;
-- Copy expression for later processing by the procedures -- Copy expression for later processing by the procedures
-- Check_Aspect_At_[Freeze_Point | End_Of_Declarations] -- Check_Aspect_At_[Freeze_Point | End_Of_Declarations]
......
...@@ -15247,27 +15247,24 @@ package body Sem_Prag is ...@@ -15247,27 +15247,24 @@ package body Sem_Prag is
-- Make_Aspect_For_PPC_In_Gen_Sub_Decl -- -- Make_Aspect_For_PPC_In_Gen_Sub_Decl --
----------------------------------------- -----------------------------------------
-- Convert any PPC and pragmas that appear within a generic subprogram
-- declaration into aspect.
procedure Make_Aspect_For_PPC_In_Gen_Sub_Decl (Decl : Node_Id) is procedure Make_Aspect_For_PPC_In_Gen_Sub_Decl (Decl : Node_Id) is
Aspects : constant List_Id := New_List; Aspects : constant List_Id := New_List;
Loc : constant Source_Ptr := Sloc (Decl); Loc : constant Source_Ptr := Sloc (Decl);
Or_Decl : constant Node_Id := Original_Node (Decl); Or_Decl : constant Node_Id := Original_Node (Decl);
Aspect : Node_Id; Aspect : Node_Id;
Original_Aspects : List_Id; Original_Aspects : List_Id;
-- To capture global references, a copy of the created aspects must be -- To capture global references, a copy of the created aspects must be
-- inserted in the original tree. -- inserted in the original tree.
Prag : Node_Id; Prag : Node_Id;
Prag_Arg_Ass : Node_Id; Prag_Arg_Ass : Node_Id;
Prag_Id : Pragma_Id; Prag_Id : Pragma_Id;
begin begin
Prag := Next (Decl);
-- Check for any PPC pragmas that appear within Decl -- Check for any PPC pragmas that appear within Decl
Prag := Next (Decl);
while Nkind (Prag) = N_Pragma loop while Nkind (Prag) = N_Pragma loop
Prag_Id := Get_Pragma_Id (Chars (Pragma_Identifier (Prag))); Prag_Id := Get_Pragma_Id (Chars (Pragma_Identifier (Prag)));
...@@ -15298,18 +15295,20 @@ package body Sem_Prag is ...@@ -15298,18 +15295,20 @@ package body Sem_Prag is
-- Set all new aspects into the generic declaration node -- Set all new aspects into the generic declaration node
if Is_Non_Empty_List (Aspects) then if Is_Non_Empty_List (Aspects) then
-- Create the list of aspects which will be inserted in the original
-- tree. -- Create the list of aspects to be inserted in the original tree
Original_Aspects := Copy_Separate_List (Aspects); Original_Aspects := Copy_Separate_List (Aspects);
-- Check if Decl already has aspects -- Check if Decl already has aspects
-- Attach the new lists of aspects to both the generic copy and the -- Attach the new lists of aspects to both the generic copy and the
-- original tree. -- original tree.
if Has_Aspects (Decl) then if Has_Aspects (Decl) then
Append_List (Aspects, Aspect_Specifications (Decl)); Append_List (Aspects, Aspect_Specifications (Decl));
Append_List (Original_Aspects, Aspect_Specifications (Or_Decl)); Append_List (Original_Aspects, Aspect_Specifications (Or_Decl));
else else
Set_Parent (Aspects, Decl); Set_Parent (Aspects, Decl);
Set_Aspect_Specifications (Decl, Aspects); Set_Aspect_Specifications (Decl, Aspects);
...@@ -15335,9 +15334,7 @@ package body Sem_Prag is ...@@ -15335,9 +15334,7 @@ package body Sem_Prag is
-- In ASIS mode, for a pragma generated from a source aspect, also -- In ASIS mode, for a pragma generated from a source aspect, also
-- analyze the original aspect expression. -- analyze the original aspect expression.
if ASIS_Mode if ASIS_Mode and then Present (Corresponding_Aspect (N)) then
and then Present (Corresponding_Aspect (N))
then
Preanalyze_Spec_Expression Preanalyze_Spec_Expression
(Original_Node (Get_Pragma_Arg (Arg_Req)), Standard_Boolean); (Original_Node (Get_Pragma_Arg (Arg_Req)), Standard_Boolean);
end if; end if;
...@@ -15350,9 +15347,7 @@ package body Sem_Prag is ...@@ -15350,9 +15347,7 @@ package body Sem_Prag is
-- In ASIS mode, for a pragma generated from a source aspect, also -- In ASIS mode, for a pragma generated from a source aspect, also
-- analyze the original aspect expression. -- analyze the original aspect expression.
if ASIS_Mode if ASIS_Mode and then Present (Corresponding_Aspect (N)) then
and then Present (Corresponding_Aspect (N))
then
Preanalyze_Spec_Expression Preanalyze_Spec_Expression
(Original_Node (Get_Pragma_Arg (Arg_Ens)), Standard_Boolean); (Original_Node (Get_Pragma_Arg (Arg_Ens)), Standard_Boolean);
end if; end if;
......
...@@ -113,9 +113,8 @@ package Sem_Prag is ...@@ -113,9 +113,8 @@ package Sem_Prag is
procedure Make_Aspect_For_PPC_In_Gen_Sub_Decl (Decl : Node_Id); procedure Make_Aspect_For_PPC_In_Gen_Sub_Decl (Decl : Node_Id);
-- This routine makes aspects from precondition or postcondition pragmas -- This routine makes aspects from precondition or postcondition pragmas
-- that appear within a generic subprogram declaration. Decl is the generic -- that appear within a generic subprogram declaration. Decl is the generic
-- subprogram declaration node. -- subprogram declaration node. Note that the aspects are attached to the
-- Note that the aspects are attached to the generic copy and also to the -- generic copy and also to the orginal tree.
-- orginal tree.
procedure Process_Compilation_Unit_Pragmas (N : Node_Id); procedure Process_Compilation_Unit_Pragmas (N : Node_Id);
-- Called at the start of processing compilation unit N to deal with any -- Called at the start of processing compilation unit N to deal with any
......
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