Commit 03e1048e by Arnaud Charlet

[multiple changes]

2011-11-20  Robert Dewar  <dewar@adacore.com>

	* exp_ch6.adb, exp_util.adb: Minor reformatting

2011-11-20  Eric Botcazou  <ebotcazou@adacore.com>

	* sinfo.ads (Reference): Document that it is OK to set
	Is_Known_Non_Null on a temporary initialized to a N_Reference
	node.

2011-11-20  Matthew Heaney  <heaney@adacore.com>

	* a-cbdlli.adb, a-cfdlli.adb (Move): Set Last component to 0
	for Source list.

From-SVN: r181530
parent 74cab21a
2011-11-20 Robert Dewar <dewar@adacore.com>
* exp_ch6.adb, exp_util.adb: Minor reformatting
2011-11-20 Eric Botcazou <ebotcazou@adacore.com>
* sinfo.ads (Reference): Document that it is OK to set
Is_Known_Non_Null on a temporary initialized to a N_Reference
node.
2011-11-20 Matthew Heaney <heaney@adacore.com>
* a-cbdlli.adb, a-cfdlli.adb (Move): Set Last component to 0
for Source list.
2011-11-20 Eric Botcazou <ebotcazou@adacore.com> 2011-11-20 Eric Botcazou <ebotcazou@adacore.com>
* exp_ch6.adb (Make_Build_In_Place_Call_In_Assignment): * exp_ch6.adb (Make_Build_In_Place_Call_In_Assignment):
......
...@@ -1164,18 +1164,67 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is ...@@ -1164,18 +1164,67 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is
"attempt to tamper with cursors of Source (list is busy)"; "attempt to tamper with cursors of Source (list is busy)";
end if; end if;
Clear (Target); Clear (Target); -- checks busy bit of Target
while Source.Length > 1 loop
pragma Assert (Source.First in 1 .. Source.Capacity);
pragma Assert (Source.Last /= Source.First);
pragma Assert (N (Source.First).Prev = 0);
pragma Assert (N (Source.Last).Next = 0);
-- Copy first element from Source to Target
while Source.Length > 0 loop
X := Source.First; X := Source.First;
Append (Target, N (X).Element); Append (Target, N (X).Element);
-- Unlink first node of Source
Source.First := N (X).Next; Source.First := N (X).Next;
N (Source.First).Prev := 0; N (Source.First).Prev := 0;
Source.Length := Source.Length - 1; Source.Length := Source.Length - 1;
-- The representation invariants for Source have been restored. It is
-- now safe to free the unlinked node, without fear of corrupting the
-- active links of Source.
-- Note that the algorithm we use here models similar algorithms used
-- in the unbounded form of the doubly-linked list container. In that
-- case, Free is an instantation of Unchecked_Deallocation, which can
-- fail (because PE will be raised if controlled Finalize fails), so
-- we must defer the call until the very last step. Here in the
-- bounded form, Free merely links the node we have just
-- "deallocated" onto a list of inactive nodes, so technically Free
-- cannot fail. However, for consistency, we handle Free the same way
-- here as we do for the unbounded form, with the pessimistic
-- assumption that it can fail.
Free (Source, X); Free (Source, X);
end loop; end loop;
if Source.Length = 1 then
pragma Assert (Source.First in 1 .. Source.Capacity);
pragma Assert (Source.Last = Source.First);
pragma Assert (N (Source.First).Prev = 0);
pragma Assert (N (Source.Last).Next = 0);
-- Copy element from Source to Target
X := Source.First;
Append (Target, N (X).Element);
-- Unlink node of Source
Source.First := 0;
Source.Last := 0;
Source.Length := 0;
-- Return the unlinked node to the free store
Free (Source, X);
end if;
end Move; end Move;
---------- ----------
......
...@@ -1007,16 +1007,65 @@ package body Ada.Containers.Formal_Doubly_Linked_Lists is ...@@ -1007,16 +1007,65 @@ package body Ada.Containers.Formal_Doubly_Linked_Lists is
Clear (Target); Clear (Target);
while Source.Length > 0 loop while Source.Length > 1 loop
pragma Assert (Source.First in 1 .. Source.Capacity);
pragma Assert (Source.Last /= Source.First);
pragma Assert (N (Source.First).Prev = 0);
pragma Assert (N (Source.Last).Next = 0);
-- Copy first element from Source to Target
X := Source.First; X := Source.First;
Append (Target, N (X).Element); -- optimize away??? Append (Target, N (X).Element); -- optimize away???
-- Unlink first node of Source
Source.First := N (X).Next; Source.First := N (X).Next;
N (Source.First).Prev := 0; N (Source.First).Prev := 0;
Source.Length := Source.Length - 1; Source.Length := Source.Length - 1;
-- The representation invariants for Source have been restored. It is
-- now safe to free the unlinked node, without fear of corrupting the
-- active links of Source.
-- Note that the algorithm we use here models similar algorithms used
-- in the unbounded form of the doubly-linked list container. In that
-- case, Free is an instantation of Unchecked_Deallocation, which can
-- fail (because PE will be raised if controlled Finalize fails), so
-- we must defer the call until the very last step. Here in the
-- bounded form, Free merely links the node we have just
-- "deallocated" onto a list of inactive nodes, so technically Free
-- cannot fail. However, for consistency, we handle Free the same way
-- here as we do for the unbounded form, with the pessimistic
-- assumption that it can fail.
Free (Source, X); Free (Source, X);
end loop; end loop;
if Source.Length = 1 then
pragma Assert (Source.First in 1 .. Source.Capacity);
pragma Assert (Source.Last = Source.First);
pragma Assert (N (Source.First).Prev = 0);
pragma Assert (N (Source.Last).Next = 0);
-- Copy element from Source to Target
X := Source.First;
Append (Target, N (X).Element);
-- Unlink node of Source
Source.First := 0;
Source.Last := 0;
Source.Length := 0;
-- Return the unlinked node to the free store
Free (Source, X);
end if;
end Move; end Move;
---------- ----------
......
...@@ -8034,7 +8034,8 @@ package body Exp_Ch6 is ...@@ -8034,7 +8034,8 @@ package body Exp_Ch6 is
Insert_After_And_Analyze (Assign, Ptr_Typ_Decl); Insert_After_And_Analyze (Assign, Ptr_Typ_Decl);
-- Finally, create an access object initialized to a reference to the -- Finally, create an access object initialized to a reference to the
-- function call. -- function call. We know this access value is non-null, so mark the
-- entity accordingly to suppress junk access checks.
New_Expr := Make_Reference (Loc, Relocate_Node (Func_Call)); New_Expr := Make_Reference (Loc, Relocate_Node (Func_Call));
...@@ -8299,7 +8300,8 @@ package body Exp_Ch6 is ...@@ -8299,7 +8300,8 @@ package body Exp_Ch6 is
end if; end if;
-- Finally, create an access object initialized to a reference to the -- Finally, create an access object initialized to a reference to the
-- function call. -- function call. We know this access value cannot be null, so mark the
-- entity accordingly to suppress the access check.
New_Expr := Make_Reference (Loc, Relocate_Node (Func_Call)); New_Expr := Make_Reference (Loc, Relocate_Node (Func_Call));
......
...@@ -6710,6 +6710,10 @@ package body Exp_Util is ...@@ -6710,6 +6710,10 @@ package body Exp_Util is
if Alfa_Mode then if Alfa_Mode then
New_Exp := E; New_Exp := E;
-- Otherwise generate reference, marking the value as non-null
-- since we know it cannot be null and we don't want a check.
else else
New_Exp := Make_Reference (Loc, E); New_Exp := Make_Reference (Loc, E);
Set_Is_Known_Non_Null (Def_Id); Set_Is_Known_Non_Null (Def_Id);
......
...@@ -7310,6 +7310,11 @@ package Sinfo is ...@@ -7310,6 +7310,11 @@ package Sinfo is
-- more sense to call it an Expression field, but then we would have to -- more sense to call it an Expression field, but then we would have to
-- special case the treatment of the N_Reference node. -- special case the treatment of the N_Reference node.
-- Note: evaluating a N_Reference node is guaranteed to yield a non-null
-- value at run time. Therefore, it is valid to set Is_Known_Non_Null on
-- a temporary initialized to a N_Reference node in order to eliminate
-- superfluous access checks.
-- Sprint syntax: prefix'reference -- Sprint syntax: prefix'reference
-- N_Reference -- N_Reference
......
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