summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-11 12:53:52 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-11 12:53:52 +0000
commit73b8a26e7ea22cb4b0fe94c634e5c96e6080e1e7 (patch)
treea26ebfc6e4caf0177dd7ef55f130557b48b5a867 /gcc
parentff9f169bc9bb93fa709b16b8ef4d5f664b3fe66c (diff)
downloadppe42-gcc-73b8a26e7ea22cb4b0fe94c634e5c96e6080e1e7.tar.gz
ppe42-gcc-73b8a26e7ea22cb4b0fe94c634e5c96e6080e1e7.zip
2013-04-11 Johannes Kanig <kanig@adacore.com>
* debug.adb: Document usage of -gnatd.Q switch. 2013-04-11 Matthew Heaney <heaney@adacore.com> * a-crbtgk.adb (Ceiling, Find, Floor): Adjust locks before element comparisons. (Generic_Conditional_Insert, Generic_Conditional_Insert_With_Hint): Ditto. * a-crbtgo.adb, a-rbtgbo.adb (Generic_Equal): Adjust locks before element comparisons. * a-rbtgso.adb (Difference, Intersection): Adjust locks before element comparisons. (Is_Subset, Overlap): Ditto (Symmetric_Difference, Union): Ditto * a-btgbso.adb (Set_Difference, Set_Intersection): Adjust locks before element comparisons. (Set_Subset, Set_Overlap): Ditto (Set_Symmetric_Difference, Set_Union): Ditto * a-coorse.adb, a-ciorse.adb, a-cborse.adb (Update_Element_Preserving_Key): Adjust locks before element comparisons (Replace_Element): Ditto 2013-04-11 Pascal Obry <obry@adacore.com> * prj-attr.adb, projects.texi, snames.ads-tmpl: Remove Build_Slaves attribute. 2013-04-11 Ed Schonberg <schonberg@adacore.com> * exp_ch3.adb (Build_Equivalent_Aggregate): Subsidiary of Expand_N_Object_Declaration, used to construct an aggregate with static components whenever possible, so that objects of a discriminated type can be initialized without calling the init. proc for the type. 2013-04-11 Vincent Celier <celier@adacore.com> * prj-makr.adb (Process_Directory): On VMS, always delete, then recreate the temporary file with Create_Output_Text_File, otherwise the output redirection does not work properly. 2013-04-11 Eric Botcazou <ebotcazou@adacore.com> * urealp.ads: Fix minor typo. 2013-04-11 Fabien Chouteau <chouteau@adacore.com> * cio.c (mktemp): Don't use tmpnam function from the system on VxWorks in kernel mode. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197784 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog52
-rw-r--r--gcc/ada/a-btgbso.adb730
-rw-r--r--gcc/ada/a-cborse.adb123
-rw-r--r--gcc/ada/a-ciorse.adb120
-rw-r--r--gcc/ada/a-coorse.adb128
-rw-r--r--gcc/ada/a-crbtgk.adb280
-rw-r--r--gcc/ada/a-crbtgo.adb40
-rw-r--r--gcc/ada/a-rbtgbo.adb39
-rw-r--r--gcc/ada/a-rbtgso.adb685
-rw-r--r--gcc/ada/cio.c16
-rw-r--r--gcc/ada/debug.adb5
-rw-r--r--gcc/ada/exp_ch3.adb144
-rw-r--r--gcc/ada/prj-attr.adb3
-rw-r--r--gcc/ada/prj-makr.adb9
-rw-r--r--gcc/ada/projects.texi25
-rw-r--r--gcc/ada/snames.ads-tmpl1
-rw-r--r--gcc/ada/urealp.ads6
17 files changed, 1911 insertions, 495 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 56fa2a2590f..19a47005d3f 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,55 @@
+2013-04-11 Johannes Kanig <kanig@adacore.com>
+
+ * debug.adb: Document usage of -gnatd.Q switch.
+
+2013-04-11 Matthew Heaney <heaney@adacore.com>
+
+ * a-crbtgk.adb (Ceiling, Find, Floor): Adjust locks
+ before element comparisons.
+ (Generic_Conditional_Insert, Generic_Conditional_Insert_With_Hint):
+ Ditto.
+ * a-crbtgo.adb, a-rbtgbo.adb (Generic_Equal): Adjust locks before
+ element comparisons.
+ * a-rbtgso.adb (Difference, Intersection): Adjust locks
+ before element comparisons.
+ (Is_Subset, Overlap): Ditto
+ (Symmetric_Difference, Union): Ditto
+ * a-btgbso.adb (Set_Difference, Set_Intersection): Adjust locks
+ before element comparisons.
+ (Set_Subset, Set_Overlap): Ditto
+ (Set_Symmetric_Difference, Set_Union): Ditto
+ * a-coorse.adb, a-ciorse.adb, a-cborse.adb
+ (Update_Element_Preserving_Key): Adjust locks before element
+ comparisons (Replace_Element): Ditto
+
+2013-04-11 Pascal Obry <obry@adacore.com>
+
+ * prj-attr.adb, projects.texi, snames.ads-tmpl: Remove Build_Slaves
+ attribute.
+
+2013-04-11 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch3.adb (Build_Equivalent_Aggregate): Subsidiary of
+ Expand_N_Object_Declaration, used to construct an aggregate
+ with static components whenever possible, so that objects of a
+ discriminated type can be initialized without calling the init.
+ proc for the type.
+
+2013-04-11 Vincent Celier <celier@adacore.com>
+
+ * prj-makr.adb (Process_Directory): On VMS, always delete,
+ then recreate the temporary file with Create_Output_Text_File,
+ otherwise the output redirection does not work properly.
+
+2013-04-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * urealp.ads: Fix minor typo.
+
+2013-04-11 Fabien Chouteau <chouteau@adacore.com>
+
+ * cio.c (mktemp): Don't use tmpnam function from the
+ system on VxWorks in kernel mode.
+
2013-04-11 Vincent Celier <celier@adacore.com>
* make.adb (Compile): Clarify the error message reported
diff --git a/gcc/ada/a-btgbso.adb b/gcc/ada/a-btgbso.adb
index b62007aafb3..2aef270f64d 100644
--- a/gcc/ada/a-btgbso.adb
+++ b/gcc/ada/a-btgbso.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2013, Free Software Foundation, Inc. --
-- --
-- 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- --
@@ -53,11 +53,19 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
----------------
procedure Set_Difference (Target : in out Set_Type; Source : Set_Type) is
+ BT : Natural renames Target.Busy;
+ LT : Natural renames Target.Lock;
+
+ BS : Natural renames Source'Unrestricted_Access.Busy;
+ LS : Natural renames Source'Unrestricted_Access.Lock;
+
Tgt, Src : Count_Type;
TN : Nodes_Type renames Target.Nodes;
SN : Nodes_Type renames Source.Nodes;
+ Compare : Integer;
+
begin
if Target'Address = Source'Address then
if Target.Busy > 0 then
@@ -82,17 +90,51 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
Src := Source.First;
loop
if Tgt = 0 then
- return;
+ exit;
end if;
if Src = 0 then
- return;
+ exit;
end if;
- if Is_Less (TN (Tgt), SN (Src)) then
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ begin
+ BT := BT + 1;
+ LT := LT + 1;
+
+ BS := BS + 1;
+ LS := LS + 1;
+
+ if Is_Less (TN (Tgt), SN (Src)) then
+ Compare := -1;
+ elsif Is_Less (SN (Src), TN (Tgt)) then
+ Compare := 1;
+ else
+ Compare := 0;
+ end if;
+
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+ exception
+ when others =>
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+
+ raise;
+ end;
+
+ if Compare < 0 then
Tgt := Tree_Operations.Next (Target, Tgt);
- elsif Is_Less (SN (Src), TN (Tgt)) then
+ elsif Compare > 0 then
Src := Tree_Operations.Next (Source, Src);
else
@@ -111,12 +153,6 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
end Set_Difference;
function Set_Difference (Left, Right : Set_Type) return Set_Type is
- L_Node : Count_Type;
- R_Node : Count_Type;
-
- Dst_Node : Count_Type;
- pragma Warnings (Off, Dst_Node);
-
begin
if Left'Address = Right'Address then
return S : Set_Type (0); -- Empty set
@@ -131,15 +167,51 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
end if;
return Result : Set_Type (Left.Length) do
- L_Node := Left.First;
- R_Node := Right.First;
- loop
- if L_Node = 0 then
- return;
- end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
- if R_Node = 0 then
- while L_Node /= 0 loop
+ declare
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
+
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
+
+ L_Node : Count_Type;
+ R_Node : Count_Type;
+
+ Dst_Node : Count_Type;
+ pragma Warnings (Off, Dst_Node);
+
+ begin
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
+ L_Node := Left.First;
+ R_Node := Right.First;
+ loop
+ if L_Node = 0 then
+ exit;
+ end if;
+
+ if R_Node = 0 then
+ while L_Node /= 0 loop
+ Insert_With_Hint
+ (Dst_Set => Result,
+ Dst_Hint => 0,
+ Src_Node => Left.Nodes (L_Node),
+ Dst_Node => Dst_Node);
+
+ L_Node := Tree_Operations.Next (Left, L_Node);
+ end loop;
+
+ exit;
+ end if;
+
+ if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
Insert_With_Hint
(Dst_Set => Result,
Dst_Hint => 0,
@@ -147,28 +219,31 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
Dst_Node => Dst_Node);
L_Node := Tree_Operations.Next (Left, L_Node);
- end loop;
- return;
- end if;
+ elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
+ R_Node := Tree_Operations.Next (Right, R_Node);
- if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
- Insert_With_Hint
- (Dst_Set => Result,
- Dst_Hint => 0,
- Src_Node => Left.Nodes (L_Node),
- Dst_Node => Dst_Node);
+ else
+ L_Node := Tree_Operations.Next (Left, L_Node);
+ R_Node := Tree_Operations.Next (Right, R_Node);
+ end if;
+ end loop;
- L_Node := Tree_Operations.Next (Left, L_Node);
+ BL := BL - 1;
+ LL := LL - 1;
- elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
- R_Node := Tree_Operations.Next (Right, R_Node);
+ BR := BR - 1;
+ LR := LR - 1;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
- else
- L_Node := Tree_Operations.Next (Left, L_Node);
- R_Node := Tree_Operations.Next (Right, R_Node);
- end if;
- end loop;
+ BR := BR - 1;
+ LR := LR - 1;
+
+ raise;
+ end;
end return;
end Set_Difference;
@@ -180,9 +255,17 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
(Target : in out Set_Type;
Source : Set_Type)
is
+ BT : Natural renames Target.Busy;
+ LT : Natural renames Target.Lock;
+
+ BS : Natural renames Source'Unrestricted_Access.Busy;
+ LS : Natural renames Source'Unrestricted_Access.Lock;
+
Tgt : Count_Type;
Src : Count_Type;
+ Compare : Integer;
+
begin
if Target'Address = Source'Address then
return;
@@ -203,7 +286,41 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
while Tgt /= 0
and then Src /= 0
loop
- if Is_Less (Target.Nodes (Tgt), Source.Nodes (Src)) then
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ begin
+ BT := BT + 1;
+ LT := LT + 1;
+
+ BS := BS + 1;
+ LS := LS + 1;
+
+ if Is_Less (Target.Nodes (Tgt), Source.Nodes (Src)) then
+ Compare := -1;
+ elsif Is_Less (Source.Nodes (Src), Target.Nodes (Tgt)) then
+ Compare := 1;
+ else
+ Compare := 0;
+ end if;
+
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+ exception
+ when others =>
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+
+ raise;
+ end;
+
+ if Compare < 0 then
declare
X : constant Count_Type := Tgt;
begin
@@ -213,7 +330,7 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
Tree_Operations.Free (Target, X);
end;
- elsif Is_Less (Source.Nodes (Src), Target.Nodes (Tgt)) then
+ elsif Compare > 0 then
Src := Tree_Operations.Next (Source, Src);
else
@@ -235,46 +352,80 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
end Set_Intersection;
function Set_Intersection (Left, Right : Set_Type) return Set_Type is
- L_Node : Count_Type;
- R_Node : Count_Type;
-
- Dst_Node : Count_Type;
- pragma Warnings (Off, Dst_Node);
-
begin
if Left'Address = Right'Address then
return Copy (Left);
end if;
return Result : Set_Type (Count_Type'Min (Left.Length, Right.Length)) do
- L_Node := Left.First;
- R_Node := Right.First;
- loop
- if L_Node = 0 then
- return;
- end if;
- if R_Node = 0 then
- return;
- end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
- if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
- L_Node := Tree_Operations.Next (Left, L_Node);
+ declare
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
- elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
- R_Node := Tree_Operations.Next (Right, R_Node);
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
- else
- Insert_With_Hint
- (Dst_Set => Result,
- Dst_Hint => 0,
- Src_Node => Left.Nodes (L_Node),
- Dst_Node => Dst_Node);
+ L_Node : Count_Type;
+ R_Node : Count_Type;
- L_Node := Tree_Operations.Next (Left, L_Node);
- R_Node := Tree_Operations.Next (Right, R_Node);
- end if;
- end loop;
+ Dst_Node : Count_Type;
+ pragma Warnings (Off, Dst_Node);
+
+ begin
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
+ L_Node := Left.First;
+ R_Node := Right.First;
+ loop
+ if L_Node = 0 then
+ exit;
+ end if;
+
+ if R_Node = 0 then
+ exit;
+ end if;
+
+ if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
+ L_Node := Tree_Operations.Next (Left, L_Node);
+
+ elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
+ R_Node := Tree_Operations.Next (Right, R_Node);
+
+ else
+ Insert_With_Hint
+ (Dst_Set => Result,
+ Dst_Hint => 0,
+ Src_Node => Left.Nodes (L_Node),
+ Dst_Node => Dst_Node);
+
+ L_Node := Tree_Operations.Next (Left, L_Node);
+ R_Node := Tree_Operations.Next (Right, R_Node);
+ end if;
+ end loop;
+
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ raise;
+ end;
end return;
end Set_Intersection;
@@ -286,9 +437,6 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
(Subset : Set_Type;
Of_Set : Set_Type) return Boolean
is
- Subset_Node : Count_Type;
- Set_Node : Count_Type;
-
begin
if Subset'Address = Of_Set'Address then
return True;
@@ -298,28 +446,75 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
return False;
end if;
- Subset_Node := Subset.First;
- Set_Node := Of_Set.First;
- loop
- if Set_Node = 0 then
- return Subset_Node = 0;
- end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
- if Subset_Node = 0 then
- return True;
- end if;
+ declare
+ BL : Natural renames Subset'Unrestricted_Access.Busy;
+ LL : Natural renames Subset'Unrestricted_Access.Lock;
- if Is_Less (Subset.Nodes (Subset_Node), Of_Set.Nodes (Set_Node)) then
- return False;
- end if;
+ BR : Natural renames Of_Set'Unrestricted_Access.Busy;
+ LR : Natural renames Of_Set'Unrestricted_Access.Lock;
- if Is_Less (Of_Set.Nodes (Set_Node), Subset.Nodes (Subset_Node)) then
- Set_Node := Tree_Operations.Next (Of_Set, Set_Node);
- else
- Set_Node := Tree_Operations.Next (Of_Set, Set_Node);
- Subset_Node := Tree_Operations.Next (Subset, Subset_Node);
- end if;
- end loop;
+ Subset_Node : Count_Type;
+ Set_Node : Count_Type;
+
+ Result : Boolean;
+
+ begin
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
+ Subset_Node := Subset.First;
+ Set_Node := Of_Set.First;
+ loop
+ if Set_Node = 0 then
+ Result := Subset_Node = 0;
+ exit;
+ end if;
+
+ if Subset_Node = 0 then
+ Result := True;
+ exit;
+ end if;
+
+ if Is_Less (Subset.Nodes (Subset_Node),
+ Of_Set.Nodes (Set_Node))
+ then
+ Result := False;
+ exit;
+ end if;
+
+ if Is_Less (Of_Set.Nodes (Set_Node),
+ Subset.Nodes (Subset_Node))
+ then
+ Set_Node := Tree_Operations.Next (Of_Set, Set_Node);
+ else
+ Set_Node := Tree_Operations.Next (Of_Set, Set_Node);
+ Subset_Node := Tree_Operations.Next (Subset, Subset_Node);
+ end if;
+ end loop;
+
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ return Result;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ raise;
+ end;
end Set_Subset;
-------------
@@ -327,33 +522,72 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
-------------
function Set_Overlap (Left, Right : Set_Type) return Boolean is
- L_Node : Count_Type;
- R_Node : Count_Type;
-
begin
if Left'Address = Right'Address then
return Left.Length /= 0;
end if;
- L_Node := Left.First;
- R_Node := Right.First;
- loop
- if L_Node = 0
- or else R_Node = 0
- then
- return False;
- end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
- if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
- L_Node := Tree_Operations.Next (Left, L_Node);
+ declare
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
- elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
- R_Node := Tree_Operations.Next (Right, R_Node);
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
- else
- return True;
- end if;
- end loop;
+ L_Node : Count_Type;
+ R_Node : Count_Type;
+
+ Result : Boolean;
+
+ begin
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
+ L_Node := Left.First;
+ R_Node := Right.First;
+ loop
+ if L_Node = 0
+ or else R_Node = 0
+ then
+ Result := False;
+ exit;
+ end if;
+
+ if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
+ L_Node := Tree_Operations.Next (Left, L_Node);
+
+ elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
+ R_Node := Tree_Operations.Next (Right, R_Node);
+
+ else
+ Result := True;
+ exit;
+ end if;
+ end loop;
+
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ return Result;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ raise;
+ end;
end Set_Overlap;
--------------------------
@@ -364,18 +598,21 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
(Target : in out Set_Type;
Source : Set_Type)
is
+ BT : Natural renames Target.Busy;
+ LT : Natural renames Target.Lock;
+
+ BS : Natural renames Source'Unrestricted_Access.Busy;
+ LS : Natural renames Source'Unrestricted_Access.Lock;
+
Tgt : Count_Type;
Src : Count_Type;
New_Tgt_Node : Count_Type;
pragma Warnings (Off, New_Tgt_Node);
- begin
- if Target.Busy > 0 then
- raise Program_Error with
- "attempt to tamper with cursors (container is busy)";
- end if;
+ Compare : Integer;
+ begin
if Target'Address = Source'Address then
Tree_Operations.Clear_Tree (Target);
return;
@@ -402,10 +639,44 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
return;
end if;
- if Is_Less (Target.Nodes (Tgt), Source.Nodes (Src)) then
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ begin
+ BT := BT + 1;
+ LT := LT + 1;
+
+ BS := BS + 1;
+ LS := LS + 1;
+
+ if Is_Less (Target.Nodes (Tgt), Source.Nodes (Src)) then
+ Compare := -1;
+ elsif Is_Less (Source.Nodes (Src), Target.Nodes (Tgt)) then
+ Compare := 1;
+ else
+ Compare := 0;
+ end if;
+
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+ exception
+ when others =>
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+
+ raise;
+ end;
+
+ if Compare < 0 then
Tgt := Tree_Operations.Next (Target, Tgt);
- elsif Is_Less (Source.Nodes (Src), Target.Nodes (Tgt)) then
+ elsif Compare > 0 then
Insert_With_Hint
(Dst_Set => Target,
Dst_Hint => Tgt,
@@ -432,12 +703,6 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
function Set_Symmetric_Difference
(Left, Right : Set_Type) return Set_Type
is
- L_Node : Count_Type;
- R_Node : Count_Type;
-
- Dst_Node : Count_Type;
- pragma Warnings (Off, Dst_Node);
-
begin
if Left'Address = Right'Address then
return S : Set_Type (0); -- Empty set
@@ -452,25 +717,62 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
end if;
return Result : Set_Type (Left.Length + Right.Length) do
- L_Node := Left.First;
- R_Node := Right.First;
- loop
- if L_Node = 0 then
- while R_Node /= 0 loop
- Insert_With_Hint
- (Dst_Set => Result,
- Dst_Hint => 0,
- Src_Node => Right.Nodes (R_Node),
- Dst_Node => Dst_Node);
- R_Node := Tree_Operations.Next (Right, R_Node);
- end loop;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
- return;
- end if;
+ declare
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
- if R_Node = 0 then
- while L_Node /= 0 loop
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
+
+ L_Node : Count_Type;
+ R_Node : Count_Type;
+
+ Dst_Node : Count_Type;
+ pragma Warnings (Off, Dst_Node);
+
+ begin
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
+ L_Node := Left.First;
+ R_Node := Right.First;
+ loop
+ if L_Node = 0 then
+ while R_Node /= 0 loop
+ Insert_With_Hint
+ (Dst_Set => Result,
+ Dst_Hint => 0,
+ Src_Node => Right.Nodes (R_Node),
+ Dst_Node => Dst_Node);
+
+ R_Node := Tree_Operations.Next (Right, R_Node);
+ end loop;
+
+ exit;
+ end if;
+
+ if R_Node = 0 then
+ while L_Node /= 0 loop
+ Insert_With_Hint
+ (Dst_Set => Result,
+ Dst_Hint => 0,
+ Src_Node => Left.Nodes (L_Node),
+ Dst_Node => Dst_Node);
+
+ L_Node := Tree_Operations.Next (Left, L_Node);
+ end loop;
+
+ exit;
+ end if;
+
+ if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
Insert_With_Hint
(Dst_Set => Result,
Dst_Hint => 0,
@@ -478,34 +780,37 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
Dst_Node => Dst_Node);
L_Node := Tree_Operations.Next (Left, L_Node);
- end loop;
- return;
- end if;
+ elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
+ Insert_With_Hint
+ (Dst_Set => Result,
+ Dst_Hint => 0,
+ Src_Node => Right.Nodes (R_Node),
+ Dst_Node => Dst_Node);
- if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
- Insert_With_Hint
- (Dst_Set => Result,
- Dst_Hint => 0,
- Src_Node => Left.Nodes (L_Node),
- Dst_Node => Dst_Node);
+ R_Node := Tree_Operations.Next (Right, R_Node);
- L_Node := Tree_Operations.Next (Left, L_Node);
+ else
+ L_Node := Tree_Operations.Next (Left, L_Node);
+ R_Node := Tree_Operations.Next (Right, R_Node);
+ end if;
+ end loop;
- elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
- Insert_With_Hint
- (Dst_Set => Result,
- Dst_Hint => 0,
- Src_Node => Right.Nodes (R_Node),
- Dst_Node => Dst_Node);
+ BL := BL - 1;
+ LL := LL - 1;
- R_Node := Tree_Operations.Next (Right, R_Node);
+ BR := BR - 1;
+ LR := LR - 1;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
- else
- L_Node := Tree_Operations.Next (Left, L_Node);
- R_Node := Tree_Operations.Next (Right, R_Node);
- end if;
- end loop;
+ BR := BR - 1;
+ LR := LR - 1;
+
+ raise;
+ end;
end return;
end Set_Symmetric_Difference;
@@ -541,17 +846,34 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
return;
end if;
- if Target.Busy > 0 then
- raise Program_Error with
- "attempt to tamper with cursors (container is busy)";
- end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
- -- Note that there's no way to decide a priori whether the target has
- -- enough capacity for the union with source. We cannot simply compare
- -- the sum of the existing lengths to the capacity of the target,
- -- because equivalent items from source are not included in the union.
+ declare
+ BS : Natural renames Source'Unrestricted_Access.Busy;
+ LS : Natural renames Source'Unrestricted_Access.Lock;
- Iterate (Source);
+ begin
+ BS := BS + 1;
+ LS := LS + 1;
+
+ -- Note that there's no way to decide a priori whether the target has
+ -- enough capacity for the union with source. We cannot simply
+ -- compare the sum of the existing lengths to the capacity of the
+ -- target, because equivalent items from source are not included in
+ -- the union.
+
+ Iterate (Source);
+
+ BS := BS - 1;
+ LS := LS - 1;
+ exception
+ when others =>
+ BS := BS - 1;
+ LS := LS - 1;
+
+ raise;
+ end;
end Set_Union;
function Set_Union (Left, Right : Set_Type) return Set_Type is
@@ -569,35 +891,65 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations is
end if;
return Result : Set_Type (Left.Length + Right.Length) do
- Assign (Target => Result, Source => Left);
+ declare
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
+
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
+
+ begin
+ BL := BL + 1;
+ LL := LL + 1;
- Insert_Right : declare
- Hint : Count_Type := 0;
+ BR := BR + 1;
+ LR := LR + 1;
- procedure Process (Node : Count_Type);
- pragma Inline (Process);
+ Assign (Target => Result, Source => Left);
- procedure Iterate is
- new Tree_Operations.Generic_Iteration (Process);
+ Insert_Right : declare
+ Hint : Count_Type := 0;
- -------------
- -- Process --
- -------------
+ procedure Process (Node : Count_Type);
+ pragma Inline (Process);
+
+ procedure Iterate is
+ new Tree_Operations.Generic_Iteration (Process);
+
+ -------------
+ -- Process --
+ -------------
+
+ procedure Process (Node : Count_Type) is
+ begin
+ Insert_With_Hint
+ (Dst_Set => Result,
+ Dst_Hint => Hint,
+ Src_Node => Right.Nodes (Node),
+ Dst_Node => Hint);
+ end Process;
+
+ -- Start of processing for Insert_Right
- procedure Process (Node : Count_Type) is
begin
- Insert_With_Hint
- (Dst_Set => Result,
- Dst_Hint => Hint,
- Src_Node => Right.Nodes (Node),
- Dst_Node => Hint);
- end Process;
+ Iterate (Right);
+ end Insert_Right;
- -- Start of processing for Insert_Right
+ BL := BL - 1;
+ LL := LL - 1;
- begin
- Iterate (Right);
- end Insert_Right;
+ BR := BR - 1;
+ LR := LR - 1;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ raise;
+ end;
end return;
end Set_Union;
diff --git a/gcc/ada/a-cborse.adb b/gcc/ada/a-cborse.adb
index 3131de13700..ed34b69195a 100644
--- a/gcc/ada/a-cborse.adb
+++ b/gcc/ada/a-cborse.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2012, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2013, Free Software Foundation, Inc. --
-- --
-- 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- --
@@ -979,6 +979,9 @@ package body Ada.Containers.Bounded_Ordered_Sets is
pragma Assert (Vet (Container, Position.Node),
"bad cursor in Update_Element_Preserving_Key");
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
declare
N : Node_Type renames Container.Nodes (Position.Node);
E : Element_Type renames N.Element;
@@ -987,12 +990,15 @@ package body Ada.Containers.Bounded_Ordered_Sets is
B : Natural renames Container.Busy;
L : Natural renames Container.Lock;
+ Eq : Boolean;
+
begin
B := B + 1;
L := L + 1;
begin
Process (E);
+ Eq := Equivalent_Keys (K, Key (E));
exception
when others =>
L := L - 1;
@@ -1003,7 +1009,7 @@ package body Ada.Containers.Bounded_Ordered_Sets is
L := L - 1;
B := B - 1;
- if Equivalent_Keys (K, Key (E)) then
+ if Eq then
return;
end if;
end;
@@ -1727,16 +1733,52 @@ package body Ada.Containers.Bounded_Ordered_Sets is
Hint : Count_Type;
Result : Count_Type;
Inserted : Boolean;
+ Compare : Boolean;
+
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ B : Natural renames Container.Busy;
+ L : Natural renames Container.Lock;
-- Start of processing for Replace_Element
begin
- if Item < Node.Element
- or else Node.Element < Item
- then
- null;
+ -- Replace_Element assigns value Item to the element designated by Node,
+ -- per certain semantic constraints, described as follows.
+
+ -- If Item is equivalent to the element, then element is replaced and
+ -- there's nothing else to do. This is the easy case.
+
+ -- If Item is not equivalent, then the node will (possibly) have to move
+ -- to some other place in the tree. This is slighly more complicated,
+ -- because we must ensure that Item is not equivalent to some other
+ -- element in the tree (in which case, the replacement is not allowed).
+
+ -- Determine whether Item is equivalent to element on the specified
+ -- node.
+
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := (if Item < Node.Element then False
+ elsif Node.Element < Item then False
+ else True);
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
+
+ if Compare then
+ -- Item is equivalent to the node's element, so we will not have to
+ -- move the node.
- else
if Container.Lock > 0 then
raise Program_Error with
"attempt to tamper with elements (set is locked)";
@@ -1746,12 +1788,63 @@ package body Ada.Containers.Bounded_Ordered_Sets is
return;
end if;
+ -- The replacement Item is not equivalent to the element on the
+ -- specified node, which means that it will need to be re-inserted in a
+ -- different position in the tree. We must now determine whether Item is
+ -- equivalent to some other element in the tree (which would prohibit
+ -- the assignment and hence the move).
+
+ -- Ceiling returns the smallest element equivalent or greater than the
+ -- specified Item; if there is no such element, then it returns 0.
+
Hint := Element_Keys.Ceiling (Container, Item);
- if Hint = 0 then
- null;
+ if Hint /= 0 then -- Item <= Nodes (Hint).Element
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := Item < Nodes (Hint).Element;
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
+
+ if not Compare then -- Item is equivalent to Nodes (Hint).Element
+ -- Ceiling returns an element that is equivalent or greater than
+ -- Item. If Item is "not less than" the element, then by
+ -- elimination we know that Item is equivalent to the element.
+
+ -- But this means that it is not possible to assign the value of
+ -- Item to the specified element (on Node), because a different
+ -- element (on Hint) equivalent to Item already exsits. (Were we
+ -- to change Node's element value, we would have to move Node, but
+ -- we would be unable to move the Node, because its new position
+ -- in the tree is already occupied by an equivalent element.)
+
+ raise Program_Error with "attempt to replace existing element";
+ end if;
+
+ -- Item is not equivalent to any other element in the tree
+ -- (specifically, it is less then Nodes (Hint).Element), so it is
+ -- safe to assign the value of Item to Node.Element. This means that
+ -- the node will have to move to a different position in the tree
+ -- (because its element will have a different value).
+
+ -- The nearest (greater) neighbor of Item is Hint. This will be the
+ -- insertion position of Node (because its element will have Item as
+ -- its new value).
+
+ -- If Node equals Hint, the relative position of Node does not
+ -- change. This allows us to perform an optimization: we need not
+ -- remove Node from the tree and then reinsert it with its new value,
+ -- because it would only be placed in the exact same position.
- elsif Item < Nodes (Hint).Element then
if Hint = Index then
if Container.Lock > 0 then
raise Program_Error with
@@ -1761,12 +1854,14 @@ package body Ada.Containers.Bounded_Ordered_Sets is
Node.Element := Item;
return;
end if;
-
- else
- pragma Assert (not (Nodes (Hint).Element < Item));
- raise Program_Error with "attempt to replace existing element";
end if;
+ -- If we get here, it is because Item was greater than all elements in
+ -- the tree (Hint = 0), or because Item was less than some element at a
+ -- different place in the tree (Item < Nodes (Hint).Element and Hint /=
+ -- Index). In either case, we remove Node from the tree and then insert
+ -- Item into the tree, onto the same Node.
+
Tree_Operations.Delete_Node_Sans_Free (Container, Index);
Local_Insert_With_Hint
diff --git a/gcc/ada/a-ciorse.adb b/gcc/ada/a-ciorse.adb
index a6538665a1b..4d918a5b45d 100644
--- a/gcc/ada/a-ciorse.adb
+++ b/gcc/ada/a-ciorse.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2012, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2013, Free Software Foundation, Inc. --
-- --
-- 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- --
@@ -1088,12 +1088,15 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
B : Natural renames Tree.Busy;
L : Natural renames Tree.Lock;
+ Eq : Boolean;
+
begin
B := B + 1;
L := L + 1;
begin
Process (E);
+ Eq := Equivalent_Keys (K, Key (E));
exception
when others =>
L := L - 1;
@@ -1104,7 +1107,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
L := L - 1;
B := B - 1;
- if Equivalent_Keys (K, Key (E)) then
+ if Eq then
return;
end if;
end;
@@ -1884,16 +1887,54 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
Hint : Node_Access;
Result : Node_Access;
Inserted : Boolean;
+ Compare : Boolean;
X : Element_Access := Node.Element;
- -- Start of processing for Replace_Element
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ B : Natural renames Tree.Busy;
+ L : Natural renames Tree.Lock;
+
+ -- Start of processing for Replace_Element
begin
- if Item < Node.Element.all or else Node.Element.all < Item then
- null;
+ -- Replace_Element assigns value Item to the element designated by Node,
+ -- per certain semantic constraints, described as follows.
+
+ -- If Item is equivalent to the element, then element is replaced and
+ -- there's nothing else to do. This is the easy case.
+
+ -- If Item is not equivalent, then the node will (possibly) have to move
+ -- to some other place in the tree. This is slighly more complicated,
+ -- because we must ensure that Item is not equivalent to some other
+ -- element in the tree (in which case, the replacement is not allowed).
+
+ -- Determine whether Item is equivalent to element on the specified
+ -- node.
+
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := (if Item < Node.Element.all then False
+ elsif Node.Element.all < Item then False
+ else True);
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
+
+ if Compare then
+ -- Item is equivalent to the node's element, so we will not have to
+ -- move the node.
- else
if Tree.Lock > 0 then
raise Program_Error with
"attempt to tamper with elements (set is locked)";
@@ -1914,12 +1955,62 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
return;
end if;
+ -- The replacement Item is not equivalent to the element on the
+ -- specified node, which means that it will need to be re-inserted in a
+ -- different position in the tree. We must now determine whether Item is
+ -- equivalent to some other element in the tree (which would prohibit
+ -- the assignment and hence the move).
+
+ -- Ceiling returns the smallest element equivalent or greater than the
+ -- specified Item; if there is no such element, then it returns null.
+
Hint := Element_Keys.Ceiling (Tree, Item);
- if Hint = null then
- null;
+ if Hint /= null then
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := Item < Hint.Element.all;
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
+
+ if not Compare then -- Item >= Hint.Element
+ -- Ceiling returns an element that is equivalent or greater than
+ -- Item. If Item is "not less than" the element, then by
+ -- elimination we know that Item is equivalent to the element.
+
+ -- But this means that it is not possible to assign the value of
+ -- Item to the specified element (on Node), because a different
+ -- element (on Hint) equivalent to Item already exsits. (Were we
+ -- to change Node's element value, we would have to move Node, but
+ -- we would be unable to move the Node, because its new position
+ -- in the tree is already occupied by an equivalent element.)
+
+ raise Program_Error with "attempt to replace existing element";
+ end if;
+
+ -- Item is not equivalent to any other element in the tree, so it is
+ -- safe to assign the value of Item to Node.Element. This means that
+ -- the node will have to move to a different position in the tree
+ -- (because its element will have a different value).
+
+ -- The nearest (greater) neighbor of Item is Hint. This will be the
+ -- insertion position of Node (because its element will have Item as
+ -- its new value).
+
+ -- If Node equals Hint, the relative position of Node does not
+ -- change. This allows us to perform an optimization: we need not
+ -- remove Node from the tree and then reinsert it with its new value,
+ -- because it would only be placed in the exact same position.
- elsif Item < Hint.Element.all then
if Hint = Node then
if Tree.Lock > 0 then
raise Program_Error with
@@ -1940,12 +2031,15 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
return;
end if;
-
- else
- pragma Assert (not (Hint.Element.all < Item));
- raise Program_Error with "attempt to replace existing element";
end if;
+ -- If we get here, it is because Item was greater than all elements in
+ -- the tree (Hint = null), or because Item was less than some element at
+ -- a different place in the tree (Item < Hint.Element.all). In either
+ -- case, we remove Node from the tree (without actually deallocating
+ -- it), and then insert Item into the tree, onto the same Node (so no
+ -- new node is actually allocated).
+
Tree_Operations.Delete_Node_Sans_Free (Tree, Node); -- Checks busy-bit
Local_Insert_With_Hint
diff --git a/gcc/ada/a-coorse.adb b/gcc/ada/a-coorse.adb
index f92760f573d..3f2537367bb 100644
--- a/gcc/ada/a-coorse.adb
+++ b/gcc/ada/a-coorse.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2012, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2013, Free Software Foundation, Inc. --
-- --
-- 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- --
@@ -987,12 +987,15 @@ package body Ada.Containers.Ordered_Sets is
B : Natural renames Tree.Busy;
L : Natural renames Tree.Lock;
+ Eq : Boolean;
+
begin
B := B + 1;
L := L + 1;
begin
Process (E);
+ Eq := Equivalent_Keys (K, Key (E));
exception
when others =>
L := L - 1;
@@ -1003,7 +1006,7 @@ package body Ada.Containers.Ordered_Sets is
L := L - 1;
B := B - 1;
- if Equivalent_Keys (K, Key (E)) then
+ if Eq then
return;
end if;
end;
@@ -1716,17 +1719,55 @@ package body Ada.Containers.Ordered_Sets is
return Node;
end New_Node;
- Hint : Node_Access;
- Result : Node_Access;
- Inserted : Boolean;
+ Hint : Node_Access;
+ Result : Node_Access;
+ Inserted : Boolean;
+ Compare : Boolean;
+
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ B : Natural renames Tree.Busy;
+ L : Natural renames Tree.Lock;
- -- Start of processing for Replace_Element
+ -- Start of processing for Replace_Element
begin
- if Item < Node.Element or else Node.Element < Item then
- null;
+ -- Replace_Element assigns value Item to the element designated by Node,
+ -- per certain semantic constraints.
+
+ -- If Item is equivalent to the element, then element is replaced and
+ -- there's nothing else to do. This is the easy case.
+
+ -- If Item is not equivalent, then the node will (possibly) have to move
+ -- to some other place in the tree. This is slighly more complicated,
+ -- because we must ensure that Item is not equivalent to some other
+ -- element in the tree (in which case, the replacement is not allowed).
+
+ -- Determine whether Item is equivalent to element on the specified
+ -- node.
+
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := (if Item < Node.Element then False
+ elsif Node.Element < Item then False
+ else True);
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
+
+ if Compare then
+ -- Item is equivalent to the node's element, so we will not have to
+ -- move the node.
- else
if Tree.Lock > 0 then
raise Program_Error with
"attempt to tamper with elements (set is locked)";
@@ -1736,12 +1777,62 @@ package body Ada.Containers.Ordered_Sets is
return;
end if;
+ -- The replacement Item is not equivalent to the element on the
+ -- specified node, which means that it will need to be re-inserted in a
+ -- different position in the tree. We must now determine whether Item is
+ -- equivalent to some other element in the tree (which would prohibit
+ -- the assignment and hence the move).
+
+ -- Ceiling returns the smallest element equivalent or greater than the
+ -- specified Item; if there is no such element, then it returns null.
+
Hint := Element_Keys.Ceiling (Tree, Item);
- if Hint = null then
- null;
+ if Hint /= null then
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := Item < Hint.Element;
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
+
+ if not Compare then -- Item >= Hint.Element
+ -- Ceiling returns an element that is equivalent or greater than
+ -- Item. If Item is "not less than" the element, then by
+ -- elimination we know that Item is equivalent to the element.
+
+ -- But this means that it is not possible to assign the value of
+ -- Item to the specified element (on Node), because a different
+ -- element (on Hint) equivalent to Item already exsits. (Were we
+ -- to change Node's element value, we would have to move Node, but
+ -- we would be unable to move the Node, because its new position
+ -- in the tree is already occupied by an equivalent element.)
+
+ raise Program_Error with "attempt to replace existing element";
+ end if;
+
+ -- Item is not equivalent to any other element in the tree, so it is
+ -- safe to assign the value of Item to Node.Element. This means that
+ -- the node will have to move to a different position in the tree
+ -- (because its element will have a different value).
+
+ -- The nearest (greater) neighbor of Item is Hint. This will be the
+ -- insertion position of Node (because its element will have Item as
+ -- its new value).
+
+ -- If Node equals Hint, the relative position of Node does not
+ -- change. This allows us to perform an optimization: we need not
+ -- remove Node from the tree and then reinsert it with its new value,
+ -- because it would only be placed in the exact same position.
- elsif Item < Hint.Element then
if Hint = Node then
if Tree.Lock > 0 then
raise Program_Error with
@@ -1751,15 +1842,18 @@ package body Ada.Containers.Ordered_Sets is
Node.Element := Item;
return;
end if;
-
- else
- pragma Assert (not (Hint.Element < Item));
- raise Program_Error with "attempt to replace existing element";
end if;
+ -- If we get here, it is because Item was greater than all elements in
+ -- the tree (Hint = null), or because Item was less than some element at
+ -- a different place in the tree (Item < Hint.Element). In either case,
+ -- we remove Node from the tree (without actually deallocating it), and
+ -- then insert Item into the tree, onto the same Node (so no new node is
+ -- actually allocated).
+
Tree_Operations.Delete_Node_Sans_Free (Tree, Node); -- Checks busy-bit
- Local_Insert_With_Hint
+ Local_Insert_With_Hint -- use unconditional insert here instead???
(Tree => Tree,
Position => Hint,
Key => Item,
diff --git a/gcc/ada/a-crbtgk.adb b/gcc/ada/a-crbtgk.adb
index 713e5426948..0e27e0a46de 100644
--- a/gcc/ada/a-crbtgk.adb
+++ b/gcc/ada/a-crbtgk.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2013, Free Software Foundation, Inc. --
-- --
-- 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- --
@@ -38,10 +38,19 @@ package body Ada.Containers.Red_Black_Trees.Generic_Keys is
-- AKA Lower_Bound
function Ceiling (Tree : Tree_Type; Key : Key_Type) return Node_Access is
+ B : Natural renames Tree'Unrestricted_Access.Busy;
+ L : Natural renames Tree'Unrestricted_Access.Lock;
+
Y : Node_Access;
X : Node_Access;
begin
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ B := B + 1;
+ L := L + 1;
+
X := Tree.Root;
while X /= null loop
if Is_Greater_Key_Node (Key, X) then
@@ -52,18 +61,37 @@ package body Ada.Containers.Red_Black_Trees.Generic_Keys is
end if;
end loop;
+ B := B - 1;
+ L := L - 1;
+
return Y;
+ exception
+ when others =>
+ B := B - 1;
+ L := L - 1;
+ raise;
end Ceiling;
----------
-- Find --
----------
- function Find (Tree : Tree_Type; Key : Key_Type) return Node_Access is
+ function Find (Tree : Tree_Type; Key : Key_Type) return Node_Access is
+ B : Natural renames Tree'Unrestricted_Access.Busy;
+ L : Natural renames Tree'Unrestricted_Access.Lock;
+
Y : Node_Access;
X : Node_Access;
+ Result : Node_Access;
+
begin
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ B := B + 1;
+ L := L + 1;
+
X := Tree.Root;
while X /= null loop
if Is_Greater_Key_Node (Key, X) then
@@ -75,25 +103,44 @@ package body Ada.Containers.Red_Black_Trees.Generic_Keys is
end loop;
if Y = null then
- return null;
- end if;
+ Result := null;
+
+ elsif Is_Less_Key_Node (Key, Y) then
+ Result := null;
- if Is_Less_Key_Node (Key, Y) then
- return null;
+ else
+ Result := Y;
end if;
- return Y;
+ B := B - 1;
+ L := L - 1;
+
+ return Result;
+ exception
+ when others =>
+ B := B - 1;
+ L := L - 1;
+ raise;
end Find;
-----------
-- Floor --
-----------
- function Floor (Tree : Tree_Type; Key : Key_Type) return Node_Access is
+ function Floor (Tree : Tree_Type; Key : Key_Type) return Node_Access is
+ B : Natural renames Tree'Unrestricted_Access.Busy;
+ L : Natural renames Tree'Unrestricted_Access.Lock;
+
Y : Node_Access;
X : Node_Access;
begin
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ B := B + 1;
+ L := L + 1;
+
X := Tree.Root;
while X /= null loop
if Is_Less_Key_Node (Key, X) then
@@ -104,7 +151,15 @@ package body Ada.Containers.Red_Black_Trees.Generic_Keys is
end if;
end loop;
+ B := B - 1;
+ L := L - 1;
+
return Y;
+ exception
+ when others =>
+ B := B - 1;
+ L := L - 1;
+ raise;
end Floor;
--------------------------------
@@ -117,8 +172,16 @@ package body Ada.Containers.Red_Black_Trees.Generic_Keys is
Node : out Node_Access;
Inserted : out Boolean)
is
- Y : Node_Access := null;
- X : Node_Access := Tree.Root;
+ X : Node_Access;
+ Y : Node_Access;
+
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ B : Natural renames Tree.Busy;
+ L : Natural renames Tree.Lock;
+
+ Compare : Boolean;
begin
-- This is a "conditional" insertion, meaning that the insertion request
@@ -136,12 +199,27 @@ package body Ada.Containers.Red_Black_Trees.Generic_Keys is
-- either the smallest node greater than Key (Inserted is True), or the
-- largest node less or equivalent to Key (Inserted is False).
- Inserted := True;
- while X /= null loop
- Y := X;
- Inserted := Is_Less_Key_Node (Key, X);
- X := (if Inserted then Ops.Left (X) else Ops.Right (X));
- end loop;
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ X := Tree.Root;
+ Y := null;
+ Inserted := True;
+ while X /= null loop
+ Y := X;
+ Inserted := Is_Less_Key_Node (Key, X);
+ X := (if Inserted then Ops.Left (X) else Ops.Right (X));
+ end loop;
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
if Inserted then
@@ -172,7 +250,22 @@ package body Ada.Containers.Red_Black_Trees.Generic_Keys is
-- Key is equivalent to or greater than Node. We must resolve which is
-- the case, to determine whether the conditional insertion succeeds.
- if Is_Greater_Key_Node (Key, Node) then
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := Is_Greater_Key_Node (Key, Node);
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
+
+ if Compare then
-- Key is strictly greater than Node, which means that Key is not
-- equivalent to Node. In this case, the insertion succeeds, and we
@@ -201,6 +294,15 @@ package body Ada.Containers.Red_Black_Trees.Generic_Keys is
Node : out Node_Access;
Inserted : out Boolean)
is
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ B : Natural renames Tree.Busy;
+ L : Natural renames Tree.Lock;
+
+ Test : Node_Access;
+ Compare : Boolean;
+
begin
-- The purpose of a hint is to avoid a search from the root of
-- tree. If we have it hint it means we only need to traverse the
@@ -215,9 +317,23 @@ package body Ada.Containers.Red_Black_Trees.Generic_Keys is
-- done; otherwise the hint was "wrong" and we must search.
if Position = null then -- largest
- if Tree.Last = null
- or else Is_Greater_Key_Node (Key, Tree.Last)
- then
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := Tree.Last = null
+ or else Is_Greater_Key_Node (Key, Tree.Last);
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
+
+ if Compare then
Insert_Post (Tree, Tree.Last, False, Node);
Inserted := True;
else
@@ -246,28 +362,58 @@ package body Ada.Containers.Red_Black_Trees.Generic_Keys is
-- then its neighbor must be anterior and so we insert before the
-- hint.
- if Is_Less_Key_Node (Key, Position) then
- declare
- Before : constant Node_Access := Ops.Previous (Position);
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := Is_Less_Key_Node (Key, Position);
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
- begin
- if Before = null then
- Insert_Post (Tree, Tree.First, True, Node);
- Inserted := True;
+ if Compare then
+ Test := Ops.Previous (Position); -- "before"
- elsif Is_Greater_Key_Node (Key, Before) then
- if Ops.Right (Before) = null then
- Insert_Post (Tree, Before, False, Node);
- else
- Insert_Post (Tree, Position, True, Node);
- end if;
+ if Test = null then -- new first node
+ Insert_Post (Tree, Tree.First, True, Node);
- Inserted := True;
+ Inserted := True;
+ return;
+ end if;
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := Is_Greater_Key_Node (Key, Test);
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
+
+ if Compare then
+ if Ops.Right (Test) = null then
+ Insert_Post (Tree, Test, False, Node);
else
- Conditional_Insert_Sans_Hint (Tree, Key, Node, Inserted);
+ Insert_Post (Tree, Position, True, Node);
end if;
- end;
+
+ Inserted := True;
+
+ else
+ Conditional_Insert_Sans_Hint (Tree, Key, Node, Inserted);
+ end if;
return;
end if;
@@ -278,28 +424,58 @@ package body Ada.Containers.Red_Black_Trees.Generic_Keys is
-- greater than the hint and less than the hint's next neighbor,
-- then we're done; otherwise we must search.
- if Is_Greater_Key_Node (Key, Position) then
- declare
- After : constant Node_Access := Ops.Next (Position);
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := Is_Greater_Key_Node (Key, Position);
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
- begin
- if After = null then
- Insert_Post (Tree, Tree.Last, False, Node);
- Inserted := True;
+ if Compare then
+ Test := Ops.Next (Position); -- "after"
- elsif Is_Less_Key_Node (Key, After) then
- if Ops.Right (Position) = null then
- Insert_Post (Tree, Position, False, Node);
- else
- Insert_Post (Tree, After, True, Node);
- end if;
+ if Test = null then -- new last node
+ Insert_Post (Tree, Tree.Last, False, Node);
- Inserted := True;
+ Inserted := True;
+ return;
+ end if;
+ begin
+ B := B + 1;
+ L := L + 1;
+
+ Compare := Is_Less_Key_Node (Key, Test);
+
+ L := L - 1;
+ B := B - 1;
+ exception
+ when others =>
+ L := L - 1;
+ B := B - 1;
+ raise;
+ end;
+
+ if Compare then
+ if Ops.Right (Position) = null then
+ Insert_Post (Tree, Position, False, Node);
else
- Conditional_Insert_Sans_Hint (Tree, Key, Node, Inserted);
+ Insert_Post (Tree, Test, True, Node);
end if;
- end;
+
+ Inserted := True;
+
+ else
+ Conditional_Insert_Sans_Hint (Tree, Key, Node, Inserted);
+ end if;
return;
end if;
diff --git a/gcc/ada/a-crbtgo.adb b/gcc/ada/a-crbtgo.adb
index c8ddcff02a5..adc9ab27966 100644
--- a/gcc/ada/a-crbtgo.adb
+++ b/gcc/ada/a-crbtgo.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2013, Free Software Foundation, Inc. --
-- --
-- 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- --
@@ -626,9 +626,17 @@ package body Ada.Containers.Red_Black_Trees.Generic_Operations is
-------------------
function Generic_Equal (Left, Right : Tree_Type) return Boolean is
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
+
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
+
L_Node : Node_Access;
R_Node : Node_Access;
+ Result : Boolean;
+
begin
if Left'Address = Right'Address then
return True;
@@ -638,18 +646,44 @@ package body Ada.Containers.Red_Black_Trees.Generic_Operations is
return False;
end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
L_Node := Left.First;
R_Node := Right.First;
+ Result := True;
while L_Node /= null loop
if not Is_Equal (L_Node, R_Node) then
- return False;
+ Result := False;
+ exit;
end if;
L_Node := Next (L_Node);
R_Node := Next (R_Node);
end loop;
- return True;
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ return Result;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ raise;
end Generic_Equal;
-----------------------
diff --git a/gcc/ada/a-rbtgbo.adb b/gcc/ada/a-rbtgbo.adb
index d66571396c7..27106205fba 100644
--- a/gcc/ada/a-rbtgbo.adb
+++ b/gcc/ada/a-rbtgbo.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2013, Free Software Foundation, Inc. --
-- --
-- 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- --
@@ -606,9 +606,17 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations is
-------------------
function Generic_Equal (Left, Right : Tree_Type'Class) return Boolean is
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
+
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
+
L_Node : Count_Type;
R_Node : Count_Type;
+ Result : Boolean;
+
begin
if Left'Address = Right'Address then
return True;
@@ -618,18 +626,43 @@ package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations is
return False;
end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
L_Node := Left.First;
R_Node := Right.First;
while L_Node /= 0 loop
if not Is_Equal (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
- return False;
+ Result := False;
+ exit;
end if;
L_Node := Next (Left, L_Node);
R_Node := Next (Right, R_Node);
end loop;
- return True;
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ return Result;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ raise;
end Generic_Equal;
-----------------------
diff --git a/gcc/ada/a-rbtgso.adb b/gcc/ada/a-rbtgso.adb
index 2b9b5402435..700832e710e 100644
--- a/gcc/ada/a-rbtgso.adb
+++ b/gcc/ada/a-rbtgso.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2013, Free Software Foundation, Inc. --
-- --
-- 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- --
@@ -84,8 +84,16 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
----------------
procedure Difference (Target : in out Tree_Type; Source : Tree_Type) is
- Tgt : Node_Access := Target.First;
- Src : Node_Access := Source.First;
+ BT : Natural renames Target.Busy;
+ LT : Natural renames Target.Lock;
+
+ BS : Natural renames Source'Unrestricted_Access.Busy;
+ LS : Natural renames Source'Unrestricted_Access.Lock;
+
+ Tgt : Node_Access;
+ Src : Node_Access;
+
+ Compare : Integer;
begin
if Target'Address = Source'Address then
@@ -107,19 +115,55 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
"attempt to tamper with cursors (container is busy)";
end if;
+ Tgt := Target.First;
+ Src := Source.First;
loop
if Tgt = null then
- return;
+ exit;
end if;
if Src = null then
- return;
+ exit;
end if;
- if Is_Less (Tgt, Src) then
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ begin
+ BT := BT + 1;
+ LT := LT + 1;
+
+ BS := BS + 1;
+ LS := LS + 1;
+
+ if Is_Less (Tgt, Src) then
+ Compare := -1;
+ elsif Is_Less (Src, Tgt) then
+ Compare := 1;
+ else
+ Compare := 0;
+ end if;
+
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+ exception
+ when others =>
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+
+ raise;
+ end;
+
+ if Compare < 0 then
Tgt := Tree_Operations.Next (Tgt);
- elsif Is_Less (Src, Tgt) then
+ elsif Compare > 0 then
Src := Tree_Operations.Next (Src);
else
@@ -137,34 +181,66 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
end Difference;
function Difference (Left, Right : Tree_Type) return Tree_Type is
- Tree : Tree_Type;
-
- L_Node : Node_Access := Left.First;
- R_Node : Node_Access := Right.First;
-
- Dst_Node : Node_Access;
- pragma Warnings (Off, Dst_Node);
-
begin
if Left'Address = Right'Address then
- return Tree; -- Empty set
+ return Tree_Type'(others => <>); -- Empty set
end if;
if Left.Length = 0 then
- return Tree; -- Empty set
+ return Tree_Type'(others => <>); -- Empty set
end if;
if Right.Length = 0 then
return Copy (Left);
end if;
- loop
- if L_Node = null then
- return Tree;
- end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ declare
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
+
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
+
+ Tree : Tree_Type;
+
+ L_Node : Node_Access;
+ R_Node : Node_Access;
+
+ Dst_Node : Node_Access;
+ pragma Warnings (Off, Dst_Node);
+
+ begin
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
+ L_Node := Left.First;
+ R_Node := Right.First;
+ loop
+ if L_Node = null then
+ exit;
+ end if;
+
+ if R_Node = null then
+ while L_Node /= null loop
+ Insert_With_Hint
+ (Dst_Tree => Tree,
+ Dst_Hint => null,
+ Src_Node => L_Node,
+ Dst_Node => Dst_Node);
+
+ L_Node := Tree_Operations.Next (L_Node);
+ end loop;
+
+ exit;
+ end if;
- if R_Node = null then
- while L_Node /= null loop
+ if Is_Less (L_Node, R_Node) then
Insert_With_Hint
(Dst_Tree => Tree,
Dst_Hint => null,
@@ -173,33 +249,33 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
L_Node := Tree_Operations.Next (L_Node);
- end loop;
+ elsif Is_Less (R_Node, L_Node) then
+ R_Node := Tree_Operations.Next (R_Node);
- return Tree;
- end if;
+ else
+ L_Node := Tree_Operations.Next (L_Node);
+ R_Node := Tree_Operations.Next (R_Node);
+ end if;
+ end loop;
- if Is_Less (L_Node, R_Node) then
- Insert_With_Hint
- (Dst_Tree => Tree,
- Dst_Hint => null,
- Src_Node => L_Node,
- Dst_Node => Dst_Node);
+ BL := BL - 1;
+ LL := LL - 1;
- L_Node := Tree_Operations.Next (L_Node);
+ BR := BR - 1;
+ LR := LR - 1;
- elsif Is_Less (R_Node, L_Node) then
- R_Node := Tree_Operations.Next (R_Node);
+ return Tree;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
- else
- L_Node := Tree_Operations.Next (L_Node);
- R_Node := Tree_Operations.Next (R_Node);
- end if;
- end loop;
+ BR := BR - 1;
+ LR := LR - 1;
- exception
- when others =>
- Delete_Tree (Tree.Root);
- raise;
+ Delete_Tree (Tree.Root);
+ raise;
+ end;
end Difference;
------------------
@@ -210,8 +286,16 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
(Target : in out Tree_Type;
Source : Tree_Type)
is
- Tgt : Node_Access := Target.First;
- Src : Node_Access := Source.First;
+ BT : Natural renames Target.Busy;
+ LT : Natural renames Target.Lock;
+
+ BS : Natural renames Source'Unrestricted_Access.Busy;
+ LS : Natural renames Source'Unrestricted_Access.Lock;
+
+ Tgt : Node_Access;
+ Src : Node_Access;
+
+ Compare : Integer;
begin
if Target'Address = Source'Address then
@@ -228,10 +312,46 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
return;
end if;
+ Tgt := Target.First;
+ Src := Source.First;
while Tgt /= null
and then Src /= null
loop
- if Is_Less (Tgt, Src) then
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ begin
+ BT := BT + 1;
+ LT := LT + 1;
+
+ BS := BS + 1;
+ LS := LS + 1;
+
+ if Is_Less (Tgt, Src) then
+ Compare := -1;
+ elsif Is_Less (Src, Tgt) then
+ Compare := 1;
+ else
+ Compare := 0;
+ end if;
+
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+ exception
+ when others =>
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+
+ raise;
+ end;
+
+ if Compare < 0 then
declare
X : Node_Access := Tgt;
begin
@@ -240,7 +360,7 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
Free (X);
end;
- elsif Is_Less (Src, Tgt) then
+ elsif Compare > 0 then
Src := Tree_Operations.Next (Src);
else
@@ -261,50 +381,83 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
end Intersection;
function Intersection (Left, Right : Tree_Type) return Tree_Type is
- Tree : Tree_Type;
-
- L_Node : Node_Access := Left.First;
- R_Node : Node_Access := Right.First;
-
- Dst_Node : Node_Access;
- pragma Warnings (Off, Dst_Node);
-
begin
if Left'Address = Right'Address then
return Copy (Left);
end if;
- loop
- if L_Node = null then
- return Tree;
- end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
- if R_Node = null then
- return Tree;
- end if;
+ declare
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
- if Is_Less (L_Node, R_Node) then
- L_Node := Tree_Operations.Next (L_Node);
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
- elsif Is_Less (R_Node, L_Node) then
- R_Node := Tree_Operations.Next (R_Node);
+ Tree : Tree_Type;
- else
- Insert_With_Hint
- (Dst_Tree => Tree,
- Dst_Hint => null,
- Src_Node => L_Node,
- Dst_Node => Dst_Node);
+ L_Node : Node_Access;
+ R_Node : Node_Access;
- L_Node := Tree_Operations.Next (L_Node);
- R_Node := Tree_Operations.Next (R_Node);
- end if;
- end loop;
+ Dst_Node : Node_Access;
+ pragma Warnings (Off, Dst_Node);
+
+ begin
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
+ L_Node := Left.First;
+ R_Node := Right.First;
+ loop
+ if L_Node = null then
+ exit;
+ end if;
+
+ if R_Node = null then
+ exit;
+ end if;
+
+ if Is_Less (L_Node, R_Node) then
+ L_Node := Tree_Operations.Next (L_Node);
+
+ elsif Is_Less (R_Node, L_Node) then
+ R_Node := Tree_Operations.Next (R_Node);
- exception
- when others =>
- Delete_Tree (Tree.Root);
- raise;
+ else
+ Insert_With_Hint
+ (Dst_Tree => Tree,
+ Dst_Hint => null,
+ Src_Node => L_Node,
+ Dst_Node => Dst_Node);
+
+ L_Node := Tree_Operations.Next (L_Node);
+ R_Node := Tree_Operations.Next (R_Node);
+ end if;
+ end loop;
+
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ return Tree;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ Delete_Tree (Tree.Root);
+ raise;
+ end;
end Intersection;
---------------
@@ -324,22 +477,44 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
return False;
end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
declare
- Subset_Node : Node_Access := Subset.First;
- Set_Node : Node_Access := Of_Set.First;
+ BL : Natural renames Subset'Unrestricted_Access.Busy;
+ LL : Natural renames Subset'Unrestricted_Access.Lock;
+
+ BR : Natural renames Of_Set'Unrestricted_Access.Busy;
+ LR : Natural renames Of_Set'Unrestricted_Access.Lock;
+
+ Subset_Node : Node_Access;
+ Set_Node : Node_Access;
+
+ Result : Boolean;
begin
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
+ Subset_Node := Subset.First;
+ Set_Node := Of_Set.First;
loop
if Set_Node = null then
- return Subset_Node = null;
+ Result := Subset_Node = null;
+ exit;
end if;
if Subset_Node = null then
- return True;
+ Result := True;
+ exit;
end if;
if Is_Less (Subset_Node, Set_Node) then
- return False;
+ Result := False;
+ exit;
end if;
if Is_Less (Set_Node, Subset_Node) then
@@ -349,6 +524,23 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
Subset_Node := Tree_Operations.Next (Subset_Node);
end if;
end loop;
+
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ return Result;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ raise;
end;
end Is_Subset;
@@ -357,31 +549,72 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
-------------
function Overlap (Left, Right : Tree_Type) return Boolean is
- L_Node : Node_Access := Left.First;
- R_Node : Node_Access := Right.First;
-
begin
if Left'Address = Right'Address then
return Left.Length /= 0;
end if;
- loop
- if L_Node = null
- or else R_Node = null
- then
- return False;
- end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
- if Is_Less (L_Node, R_Node) then
- L_Node := Tree_Operations.Next (L_Node);
+ declare
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
- elsif Is_Less (R_Node, L_Node) then
- R_Node := Tree_Operations.Next (R_Node);
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
- else
- return True;
- end if;
- end loop;
+ L_Node : Node_Access;
+ R_Node : Node_Access;
+
+ Result : Boolean;
+
+ begin
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
+ L_Node := Left.First;
+ R_Node := Right.First;
+ loop
+ if L_Node = null
+ or else R_Node = null
+ then
+ Result := False;
+ exit;
+ end if;
+
+ if Is_Less (L_Node, R_Node) then
+ L_Node := Tree_Operations.Next (L_Node);
+
+ elsif Is_Less (R_Node, L_Node) then
+ R_Node := Tree_Operations.Next (R_Node);
+
+ else
+ Result := True;
+ exit;
+ end if;
+ end loop;
+
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ return Result;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ raise;
+ end;
end Overlap;
--------------------------
@@ -392,23 +625,28 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
(Target : in out Tree_Type;
Source : Tree_Type)
is
- Tgt : Node_Access := Target.First;
- Src : Node_Access := Source.First;
+ BT : Natural renames Target.Busy;
+ LT : Natural renames Target.Lock;
+
+ BS : Natural renames Source'Unrestricted_Access.Busy;
+ LS : Natural renames Source'Unrestricted_Access.Lock;
+
+ Tgt : Node_Access;
+ Src : Node_Access;
New_Tgt_Node : Node_Access;
pragma Warnings (Off, New_Tgt_Node);
- begin
- if Target.Busy > 0 then
- raise Program_Error with
- "attempt to tamper with cursors (container is busy)";
- end if;
+ Compare : Integer;
+ begin
if Target'Address = Source'Address then
Clear (Target);
return;
end if;
+ Tgt := Target.First;
+ Src := Source.First;
loop
if Tgt = null then
while Src /= null loop
@@ -428,10 +666,44 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
return;
end if;
- if Is_Less (Tgt, Src) then
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ begin
+ BT := BT + 1;
+ LT := LT + 1;
+
+ BS := BS + 1;
+ LS := LS + 1;
+
+ if Is_Less (Tgt, Src) then
+ Compare := -1;
+ elsif Is_Less (Src, Tgt) then
+ Compare := 1;
+ else
+ Compare := 0;
+ end if;
+
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+ exception
+ when others =>
+ BT := BT - 1;
+ LT := LT - 1;
+
+ BS := BS - 1;
+ LS := LS - 1;
+
+ raise;
+ end;
+
+ if Compare < 0 then
Tgt := Tree_Operations.Next (Tgt);
- elsif Is_Less (Src, Tgt) then
+ elsif Compare > 0 then
Insert_With_Hint
(Dst_Tree => Target,
Dst_Hint => Tgt,
@@ -455,17 +727,9 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
end Symmetric_Difference;
function Symmetric_Difference (Left, Right : Tree_Type) return Tree_Type is
- Tree : Tree_Type;
-
- L_Node : Node_Access := Left.First;
- R_Node : Node_Access := Right.First;
-
- Dst_Node : Node_Access;
- pragma Warnings (Off, Dst_Node);
-
begin
if Left'Address = Right'Address then
- return Tree; -- Empty set
+ return Tree_Type'(others => <>); -- Empty set
end if;
if Right.Length = 0 then
@@ -476,70 +740,110 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
return Copy (Right);
end if;
- loop
- if L_Node = null then
- while R_Node /= null loop
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ declare
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
+
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
+
+ Tree : Tree_Type;
+
+ L_Node : Node_Access;
+ R_Node : Node_Access;
+
+ Dst_Node : Node_Access;
+ pragma Warnings (Off, Dst_Node);
+
+ begin
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
+ L_Node := Left.First;
+ R_Node := Right.First;
+ loop
+ if L_Node = null then
+ while R_Node /= null loop
+ Insert_With_Hint
+ (Dst_Tree => Tree,
+ Dst_Hint => null,
+ Src_Node => R_Node,
+ Dst_Node => Dst_Node);
+ R_Node := Tree_Operations.Next (R_Node);
+ end loop;
+
+ exit;
+ end if;
+
+ if R_Node = null then
+ while L_Node /= null loop
+ Insert_With_Hint
+ (Dst_Tree => Tree,
+ Dst_Hint => null,
+ Src_Node => L_Node,
+ Dst_Node => Dst_Node);
+
+ L_Node := Tree_Operations.Next (L_Node);
+ end loop;
+
+ exit;
+ end if;
+
+ if Is_Less (L_Node, R_Node) then
Insert_With_Hint
(Dst_Tree => Tree,
Dst_Hint => null,
- Src_Node => R_Node,
+ Src_Node => L_Node,
Dst_Node => Dst_Node);
- R_Node := Tree_Operations.Next (R_Node);
- end loop;
- return Tree;
- end if;
+ L_Node := Tree_Operations.Next (L_Node);
- if R_Node = null then
- while L_Node /= null loop
+ elsif Is_Less (R_Node, L_Node) then
Insert_With_Hint
(Dst_Tree => Tree,
Dst_Hint => null,
- Src_Node => L_Node,
+ Src_Node => R_Node,
Dst_Node => Dst_Node);
- L_Node := Tree_Operations.Next (L_Node);
- end loop;
+ R_Node := Tree_Operations.Next (R_Node);
- return Tree;
- end if;
+ else
+ L_Node := Tree_Operations.Next (L_Node);
+ R_Node := Tree_Operations.Next (R_Node);
+ end if;
+ end loop;
- if Is_Less (L_Node, R_Node) then
- Insert_With_Hint
- (Dst_Tree => Tree,
- Dst_Hint => null,
- Src_Node => L_Node,
- Dst_Node => Dst_Node);
+ BL := BL - 1;
+ LL := LL - 1;
- L_Node := Tree_Operations.Next (L_Node);
+ BR := BR - 1;
+ LR := LR - 1;
- elsif Is_Less (R_Node, L_Node) then
- Insert_With_Hint
- (Dst_Tree => Tree,
- Dst_Hint => null,
- Src_Node => R_Node,
- Dst_Node => Dst_Node);
+ return Tree;
+ exception
+ when others =>
+ BL := BL - 1;
+ LL := LL - 1;
- R_Node := Tree_Operations.Next (R_Node);
+ BR := BR - 1;
+ LR := LR - 1;
- else
- L_Node := Tree_Operations.Next (L_Node);
- R_Node := Tree_Operations.Next (R_Node);
- end if;
- end loop;
-
- exception
- when others =>
- Delete_Tree (Tree.Root);
- raise;
+ Delete_Tree (Tree.Root);
+ raise;
+ end;
end Symmetric_Difference;
-----------
-- Union --
-----------
- procedure Union (Target : in out Tree_Type; Source : Tree_Type)
- is
+ procedure Union (Target : in out Tree_Type; Source : Tree_Type) is
Hint : Node_Access;
procedure Process (Node : Node_Access);
@@ -555,7 +859,7 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
begin
Insert_With_Hint
(Dst_Tree => Target,
- Dst_Hint => Hint,
+ Dst_Hint => Hint, -- use node most recently inserted as hint
Src_Node => Node,
Dst_Node => Hint);
end Process;
@@ -567,12 +871,28 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
return;
end if;
- if Target.Busy > 0 then
- raise Program_Error with
- "attempt to tamper with cursors (container is busy)";
- end if;
+ -- Per AI05-0022, the container implementation is required to detect
+ -- element tampering by a generic actual subprogram.
+
+ declare
+ BS : Natural renames Source'Unrestricted_Access.Busy;
+ LS : Natural renames Source'Unrestricted_Access.Lock;
+
+ begin
+ BS := BS + 1;
+ LS := LS + 1;
+
+ Iterate (Source);
- Iterate (Source);
+ BS := BS - 1;
+ LS := LS - 1;
+ exception
+ when others =>
+ BS := BS - 1;
+ LS := LS - 1;
+
+ raise;
+ end;
end Union;
function Union (Left, Right : Tree_Type) return Tree_Type is
@@ -590,6 +910,12 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
end if;
declare
+ BL : Natural renames Left'Unrestricted_Access.Busy;
+ LL : Natural renames Left'Unrestricted_Access.Lock;
+
+ BR : Natural renames Right'Unrestricted_Access.Busy;
+ LR : Natural renames Right'Unrestricted_Access.Lock;
+
Tree : Tree_Type := Copy (Left);
Hint : Node_Access;
@@ -608,7 +934,7 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
begin
Insert_With_Hint
(Dst_Tree => Tree,
- Dst_Hint => Hint,
+ Dst_Hint => Hint, -- use node most recently inserted as hint
Src_Node => Node,
Dst_Node => Hint);
end Process;
@@ -616,15 +942,32 @@ package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
-- Start of processing for Union
begin
+ BL := BL + 1;
+ LL := LL + 1;
+
+ BR := BR + 1;
+ LR := LR + 1;
+
Iterate (Right);
- return Tree;
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
+ return Tree;
exception
when others =>
+ BL := BL - 1;
+ LL := LL - 1;
+
+ BR := BR - 1;
+ LR := LR - 1;
+
Delete_Tree (Tree.Root);
raise;
end;
-
end Union;
end Ada.Containers.Red_Black_Trees.Generic_Set_Operations;
diff --git a/gcc/ada/cio.c b/gcc/ada/cio.c
index ac23519ae9b..fd85df96923 100644
--- a/gcc/ada/cio.c
+++ b/gcc/ada/cio.c
@@ -6,7 +6,7 @@
* *
* C Implementation File *
* *
- * Copyright (C) 1992-2012, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2013, Free Software Foundation, Inc. *
* *
* 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- *
@@ -40,6 +40,9 @@
#include "adaint.h"
+/* We need L_tmpnam definition */
+#include <stdio.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -135,7 +138,18 @@ put_char_stderr (int c)
char *
mktemp (char *template)
{
+#if !(defined (__RTP__) || defined (VTHREADS))
+ static char buf[L_tmpnam]; /* Internal buffer for name */
+
+ /* If parameter is NULL use internal buffer */
+ if (template == NULL)
+ template = buf;
+
+ __gnat_tmp_name (template);
+ return template;
+#else
return tmpnam (NULL);
+#endif
}
#endif
diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
index cd6d30339a7..18095508a0c 100644
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -134,7 +134,7 @@ package body Debug is
-- d.N Add node to all entities
-- d.O Dump internal SCO tables
-- d.P Previous (non-optimized) handling of length comparisons
- -- d.Q
+ -- d.Q Flow Analysis mode for gnat2why
-- d.R Restrictions in ali files in positional form
-- d.S Force Optimize_Alignment (Space)
-- d.T Force Optimize_Alignment (Time)
@@ -648,6 +648,9 @@ package body Debug is
-- This is there in case we find a situation where the optimization
-- malfunctions, to provide a work around.
+ -- d.Q Flow Analysis mode for gnat2why. When this flag is given,
+ -- gnat2why will do flow analysis, and no translation to Why is done.
+
-- d.R As documented in lib-writ.ads, restrictions in the ali file can
-- have two forms, positional and named. The named notation is the
-- current preferred form, but the use of this debug switch will force
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 89ffa2b8069..35d7a9f3029 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -4825,10 +4825,146 @@ package body Exp_Ch3 is
-- which case the init proc call must be inserted only after the bodies
-- of the shared variable procedures have been seen.
+ function Build_Equivalent_Aggregate return Boolean;
+ -- If the object has a constrained discriminated type and no initial
+ -- value, it may be possible to build an equivalent aggregate instead,
+ -- and prevent an actual call to the initialization procedure.
+
function Rewrite_As_Renaming return Boolean;
-- Indicate whether to rewrite a declaration with initialization into an
-- object renaming declaration (see below).
+ --------------------------------
+ -- Build_Equivalent_Aggregate --
+ --------------------------------
+
+ function Build_Equivalent_Aggregate return Boolean is
+ Aggr : Node_Id;
+ Comp : Entity_Id;
+ Discr : Elmt_Id;
+ Full_Type : Entity_Id;
+
+ begin
+ Full_Type := Typ;
+ if Is_Private_Type (Typ)
+ and then Present (Full_View (Typ))
+ then
+ Full_Type := Full_View (Typ);
+ end if;
+
+ -- Only perform this transformation if Elaboration_Code is forbidden
+ -- or undesirable, and if this is a global entity of a constrained
+ -- record type.
+
+ -- If Initialize_Scalars might be active this transformation cannot
+ -- be performed either, because it will lead to different semantics
+ -- or because elaboration code will in fact be created.
+
+ if Ekind (Full_Type) /= E_Record_Subtype
+ or else not Has_Discriminants (Full_Type)
+ or else not Is_Constrained (Full_Type)
+ or else Is_Controlled (Full_Type)
+ or else Is_Limited_Type (Full_Type)
+ or else not Restriction_Active (No_Initialize_Scalars)
+ then
+ return False;
+ end if;
+
+ if Ekind (Current_Scope) = E_Package
+ and then
+ (Restriction_Active (No_Elaboration_Code)
+ or else Is_Preelaborated (Current_Scope))
+ then
+
+ -- Building a static aggregate is possible if the discriminants
+ -- have static values and the other components have static
+ -- defaults or none.
+
+ Discr := First_Elmt (Discriminant_Constraint (Full_Type));
+ while Present (Discr) loop
+ if not Is_OK_Static_Expression (Node (Discr)) then
+ return False;
+ end if;
+
+ Next_Elmt (Discr);
+ end loop;
+
+ -- Check that initialized components are OK, and that non-
+ -- initialized components do not require a call to their own
+ -- initialization procedure.
+
+ Comp := First_Component (Full_Type);
+ while Present (Comp) loop
+ if Ekind (Comp) = E_Component
+ and then Present (Expression (Parent (Comp)))
+ and then
+ not Is_OK_Static_Expression (Expression (Parent (Comp)))
+ then
+ return False;
+
+ elsif Has_Non_Null_Base_Init_Proc (Etype (Comp)) then
+ return False;
+
+ end if;
+
+ Next_Component (Comp);
+ end loop;
+
+ -- Everything is static, assemble the aggregate, discriminant
+ -- values first.
+
+ Aggr :=
+ Make_Aggregate (Loc,
+ Expressions => New_List,
+ Component_Associations => New_List);
+
+ Discr := First_Elmt (Discriminant_Constraint (Full_Type));
+ while Present (Discr) loop
+ Append_To (Expressions (Aggr), New_Copy (Node (Discr)));
+ Next_Elmt (Discr);
+ end loop;
+
+ -- Now collect values of initialized components.
+
+ Comp := First_Component (Full_Type);
+ while Present (Comp) loop
+ if Ekind (Comp) = E_Component
+ and then Present (Expression (Parent (Comp)))
+ then
+ Append_To (Component_Associations (Aggr),
+ Make_Component_Association (Loc,
+ Choices => New_List (New_Occurrence_Of (Comp, Loc)),
+ Expression => New_Copy_Tree
+ (Expression (Parent (Comp)))));
+ end if;
+
+ Next_Component (Comp);
+ end loop;
+
+ -- Finally, box-initialize remaining components.
+
+ Append_To (Component_Associations (Aggr),
+ Make_Component_Association (Loc,
+ Choices => New_List (Make_Others_Choice (Loc)),
+ Expression => Empty));
+ Set_Box_Present (Last (Component_Associations (Aggr)));
+ Set_Expression (N, Aggr);
+
+ if Typ /= Full_Type then
+ Analyze_And_Resolve (Aggr, Full_View (Base_Type (Full_Type)));
+ Rewrite (Aggr, Unchecked_Convert_To (Typ, Aggr));
+ Analyze_And_Resolve (Aggr, Typ);
+ else
+ Analyze_And_Resolve (Aggr, Full_Type);
+ end if;
+
+ return True;
+
+ else
+ return False;
+ end if;
+ end Build_Equivalent_Aggregate;
+
-------------------------
-- Rewrite_As_Renaming --
-------------------------
@@ -5033,6 +5169,14 @@ package body Exp_Ch3 is
(N, New_Copy_Tree (Init_Expr, New_Scope => Current_Scope));
return;
+ -- If type has discriminants, try to build equivalent
+ -- aggregate using discriminant values from the declaration.
+ -- This is a useful optimization, in particular if restriction
+ -- No_Elaboration_Code is active.
+
+ elsif Build_Equivalent_Aggregate then
+ return;
+
else
Initialization_Warning (Id_Ref);
diff --git a/gcc/ada/prj-attr.adb b/gcc/ada/prj-attr.adb
index b575edaa105..a69281130dd 100644
--- a/gcc/ada/prj-attr.adb
+++ b/gcc/ada/prj-attr.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2012, Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2013, Free Software Foundation, Inc. --
-- --
-- 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- --
@@ -365,7 +365,6 @@ package body Prj.Attr is
-- package Remote
"Premote#" &
- "LVbuild_slaves#" &
"SVroot_dir#" &
-- package Stack
diff --git a/gcc/ada/prj-makr.adb b/gcc/ada/prj-makr.adb
index 0ed805021f9..9572d6882ca 100644
--- a/gcc/ada/prj-makr.adb
+++ b/gcc/ada/prj-makr.adb
@@ -1271,6 +1271,15 @@ package body Prj.Makr is
new String'(Get_Name_String (Tmp_File));
end if;
+ -- On VMS, a file created with Create_Temp_File cannot
+ -- be used to redirect output.
+
+ if Hostparm.OpenVMS then
+ Close (FD);
+ Delete_File (Temp_File_Name.all, Success);
+ FD := Create_Output_Text_File (Temp_File_Name.all);
+ end if;
+
Args (Args'Last) := new String'
(Dir_Name &
Directory_Separator &
diff --git a/gcc/ada/projects.texi b/gcc/ada/projects.texi
index 492d23a4416..dee9b901962 100644
--- a/gcc/ada/projects.texi
+++ b/gcc/ada/projects.texi
@@ -1101,31 +1101,6 @@ The following attributes can be defined in package @code{Remote}:
@table @asis
-@item @b{Build_Slaves}
-@cindex @code{Build_Slaves}
-
-A list of string referencing the remote build slaves to use for the
-compilation phase. The format is:
-@code{[protocol://]name.domain[:port]}.
-
-Where @code{protocol} is one of:
-
-@table @asis
-
-@item rsync
-@cindex @code{rsync}
-
-The sources are copied using the external @code{rsync} tool.
-
-@item file
-
-The sources are accessed via a shared directory or mount point.
-
-@end table
-
-The default port used to communicate with @command{gprslave} is
-@code{8484}.
-
@item @b{Root_Dir}:
@cindex @code{Root_Dir}
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
index 77e2caa5a2d..0f0053ffeaa 100644
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -1205,7 +1205,6 @@ package Snames is
Name_Archive_Suffix : constant Name_Id := N + $;
Name_Binder : constant Name_Id := N + $;
Name_Body_Suffix : constant Name_Id := N + $;
- Name_Build_Slaves : constant Name_Id := N + $;
Name_Builder : constant Name_Id := N + $;
Name_Clean : constant Name_Id := N + $;
Name_Compiler : constant Name_Id := N + $;
diff --git a/gcc/ada/urealp.ads b/gcc/ada/urealp.ads
index 54fe8ffe14d..d9d63eaeca5 100644
--- a/gcc/ada/urealp.ads
+++ b/gcc/ada/urealp.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2013, Free Software Foundation, Inc. --
-- --
-- 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- --
@@ -46,7 +46,7 @@ package Urealp is
-- use the UR_Eq function).
-- A Ureal value represents an arbitrary precision universal real value,
- -- stored internally using four components
+ -- stored internally using four components:
-- the numerator (Uint, always non-negative)
-- the denominator (Uint, always non-zero, always positive if base = 0)
@@ -125,7 +125,7 @@ package Urealp is
-- Returns value 10.0 ** 36
function Ureal_M_10_36 return Ureal;
- -- Returns value -(10.0
+ -- Returns value -10.0 ** 36
-----------------
-- Subprograms --
OpenPOWER on IntegriCloud