aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2020-10-13 09:15:23 +0200
committerPierre-Marie de Rodat <derodat@adacore.com>2020-11-25 08:22:28 -0500
commit9d41d78b05f262d638fa205c7d60415321535834 (patch)
tree6785031d2339fa5097981501e207524cfabaefef
parenta8c229e14c4d6c5c6e2d1ff18741e89d7149d81d (diff)
downloadgcc-9d41d78b05f262d638fa205c7d60415321535834.zip
gcc-9d41d78b05f262d638fa205c7d60415321535834.tar.gz
gcc-9d41d78b05f262d638fa205c7d60415321535834.tar.bz2
[Ada] Adjust support for 128-bit integer types in System.Random_Numbers
gcc/ada/ * libgnat/s-rannum.adb (Random_Discrete): Specifically deal with the case where the size of the base type is larger than 64 bits.
-rw-r--r--gcc/ada/libgnat/s-rannum.adb35
1 files changed, 35 insertions, 0 deletions
diff --git a/gcc/ada/libgnat/s-rannum.adb b/gcc/ada/libgnat/s-rannum.adb
index e65e6a7..ab6428f 100644
--- a/gcc/ada/libgnat/s-rannum.adb
+++ b/gcc/ada/libgnat/s-rannum.adb
@@ -409,6 +409,41 @@ is
elsif Max < Min then
raise Constraint_Error;
+ -- In the 128-bit case, we have to be careful since not all 128-bit
+ -- unsigned values are representable in GNAT's universal integer.
+
+ elsif Result_Subtype'Base'Size > 64 then
+ declare
+ -- Ignore unequal-size warnings since GNAT's handling is correct.
+
+ pragma Warnings ("Z");
+ function Conv_To_Unsigned is
+ new Unchecked_Conversion (Result_Subtype'Base, Unsigned_128);
+ function Conv_To_Result is
+ new Unchecked_Conversion (Unsigned_128, Result_Subtype'Base);
+ pragma Warnings ("z");
+
+ N : constant Unsigned_128 :=
+ Conv_To_Unsigned (Max) - Conv_To_Unsigned (Min) + 1;
+
+ X, Slop : Unsigned_128;
+
+ begin
+ if N = 0 then
+ return Conv_To_Result (Conv_To_Unsigned (Min) + Random (Gen));
+
+ else
+ Slop := Unsigned_128'Last rem N + 1;
+
+ loop
+ X := Random (Gen);
+ exit when Slop = N or else X <= Unsigned_128'Last - Slop;
+ end loop;
+
+ return Conv_To_Result (Conv_To_Unsigned (Min) + X rem N);
+ end if;
+ end;
+
-- In the 64-bit case, we have to be careful since not all 64-bit
-- unsigned values are representable in GNAT's universal integer.