aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEd Schonberg <schonberg@adacore.com>2021-05-21 15:51:13 -0400
committerPierre-Marie de Rodat <derodat@adacore.com>2021-07-08 13:34:17 +0000
commitb927d936e339ddd47779b522b80552306ebb5604 (patch)
treeb9cceeeb9ef6537885709f2e0e4c54e742dc0894 /gcc
parentc5b1e8e9a5808d612ad20fdf2f77c52cfa5907d3 (diff)
downloadgcc-b927d936e339ddd47779b522b80552306ebb5604.zip
gcc-b927d936e339ddd47779b522b80552306ebb5604.tar.gz
gcc-b927d936e339ddd47779b522b80552306ebb5604.tar.bz2
[Ada] Incorrect iteration over hashed containers after multiple Inserts
gcc/ada/ * libgnat/a-cohama.ads: Introduce an equality operator over cursors. * libgnat/a-cohase.ads: Ditto. * libgnat/a-cohama.adb: Add body for "=" over cursors. (Insert): Do not set the Position component of the cursor that denotes the inserted element. * libgnat/a-cohase.adb: Ditto.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/libgnat/a-cohama.adb14
-rw-r--r--gcc/ada/libgnat/a-cohama.ads8
-rw-r--r--gcc/ada/libgnat/a-cohase.adb14
-rw-r--r--gcc/ada/libgnat/a-cohase.ads9
4 files changed, 41 insertions, 4 deletions
diff --git a/gcc/ada/libgnat/a-cohama.adb b/gcc/ada/libgnat/a-cohama.adb
index 26bdd55..e6d6e4d 100644
--- a/gcc/ada/libgnat/a-cohama.adb
+++ b/gcc/ada/libgnat/a-cohama.adb
@@ -116,6 +116,13 @@ is
-- "=" --
---------
+ function "=" (Left, Right : Cursor) return Boolean is
+ begin
+ return
+ Left.Container = Right.Container
+ and then Left.Node = Right.Node;
+ end "=";
+
function "=" (Left, Right : Map) return Boolean is
begin
return Is_Equal (Left.HT, Right.HT);
@@ -636,7 +643,11 @@ is
end if;
Position.Container := Container'Unrestricted_Access;
- Position.Position := HT_Ops.Index (HT, Position.Node);
+
+ -- Note that we do not set the Position component of the cursor,
+ -- because it may become incorrect on subsequent insertions/deletions
+ -- from the container. This will lose some optimizations but prevents
+ -- anomalies when the underlying hash-table is expanded or shrunk.
end Insert;
procedure Insert
@@ -679,7 +690,6 @@ is
end if;
Position.Container := Container'Unrestricted_Access;
- Position.Position := HT_Ops.Index (HT, Position.Node);
end Insert;
procedure Insert
diff --git a/gcc/ada/libgnat/a-cohama.ads b/gcc/ada/libgnat/a-cohama.ads
index a04cb3a..3f172bd 100644
--- a/gcc/ada/libgnat/a-cohama.ads
+++ b/gcc/ada/libgnat/a-cohama.ads
@@ -110,6 +110,14 @@ is
type Cursor is private;
pragma Preelaborable_Initialization (Cursor);
+ function "=" (Left, Right : Cursor) return Boolean;
+ -- The representation of cursors includes a component used to optimize
+ -- iteration over maps. This component may become unreliable after
+ -- multiple map insertions, and must be excluded from cursor equality,
+ -- so we need to provide an explicit definition for it, instead of
+ -- using predefined equality (as implied by a questionable comment
+ -- in the RM).
+
Empty_Map : constant Map;
-- Map objects declared without an initialization expression are
-- initialized to the value Empty_Map.
diff --git a/gcc/ada/libgnat/a-cohase.adb b/gcc/ada/libgnat/a-cohase.adb
index 31374f6..2342116 100644
--- a/gcc/ada/libgnat/a-cohase.adb
+++ b/gcc/ada/libgnat/a-cohase.adb
@@ -145,6 +145,13 @@ is
-- "=" --
---------
+ function "=" (Left, Right : Cursor) return Boolean is
+ begin
+ return
+ Left.Container = Right.Container
+ and then Left.Node = Right.Node;
+ end "=";
+
function "=" (Left, Right : Set) return Boolean is
begin
return Is_Equal (Left.HT, Right.HT);
@@ -763,11 +770,14 @@ is
Position : out Cursor;
Inserted : out Boolean)
is
- HT : Hash_Table_Type renames Container'Unrestricted_Access.HT;
begin
Insert (Container.HT, New_Item, Position.Node, Inserted);
Position.Container := Container'Unchecked_Access;
- Position.Position := HT_Ops.Index (HT, Position.Node);
+
+ -- Note that we do not set the Position component of the cursor,
+ -- because it may become incorrect on subsequent insertions/deletions
+ -- from the container. This will lose some optimizations but prevents
+ -- anomalies when the underlying hash-table is expanded or shrunk.
end Insert;
procedure Insert
diff --git a/gcc/ada/libgnat/a-cohase.ads b/gcc/ada/libgnat/a-cohase.ads
index f0763af..2356ba7 100644
--- a/gcc/ada/libgnat/a-cohase.ads
+++ b/gcc/ada/libgnat/a-cohase.ads
@@ -69,6 +69,15 @@ is
type Cursor is private;
pragma Preelaborable_Initialization (Cursor);
+ function "=" (Left, Right : Cursor) return Boolean;
+ -- The representation of cursors includes a component used to optimize
+ -- iteration over sets. This component may become unreliable after
+ -- multiple set insertions, and must be excluded from cursor equality,
+ -- so we need to provide an explicit definition for it, instead of
+ -- using predefined equality (as implied by a questionable comment
+ -- in the RM). This is also the case for hashed maps, and affects the
+ -- use of Insert primitives in hashed structures.
+
Empty_Set : constant Set;
-- Set objects declared without an initialization expression are
-- initialized to the value Empty_Set.