aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/libgnat
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@adacore.com>2020-06-05 05:40:55 -0400
committerPierre-Marie de Rodat <derodat@adacore.com>2020-07-16 05:17:56 -0400
commit0f6898f9d8c981eb70410bb9fd19d08ce1f684b8 (patch)
tree1067145f295f624c17fbdb7c058548d47e0b6d18 /gcc/ada/libgnat
parent7e06a62f5bb4baaf3701a9a29e03c80d2ae50a49 (diff)
downloadgcc-0f6898f9d8c981eb70410bb9fd19d08ce1f684b8.zip
gcc-0f6898f9d8c981eb70410bb9fd19d08ce1f684b8.tar.gz
gcc-0f6898f9d8c981eb70410bb9fd19d08ce1f684b8.tar.bz2
[Ada] Add centralized capacity check in Generic_Bignums
gcc/ada/ * libgnat/s-genbig.adb ("**"): Remove capacity limit check. Improve code by using an extended return. (Normalize): Perform capacity limit check here instead which is the centralized place where (potentially large) big integers are allocated.
Diffstat (limited to 'gcc/ada/libgnat')
-rw-r--r--gcc/ada/libgnat/s-genbig.adb31
1 files changed, 12 insertions, 19 deletions
diff --git a/gcc/ada/libgnat/s-genbig.adb b/gcc/ada/libgnat/s-genbig.adb
index 2f6bdd5c..71aff9b 100644
--- a/gcc/ada/libgnat/s-genbig.adb
+++ b/gcc/ada/libgnat/s-genbig.adb
@@ -98,6 +98,7 @@ package body System.Generic_Bignums is
-- Given a digit vector and sign, allocate and construct a big integer
-- value. Note that X may have leading zeroes which must be removed, and if
-- the result is zero, the sign is forced positive.
+ -- If X is too big, Storage_Error is raised.
function "**" (X : Bignum; Y : SD) return Big_Integer;
-- Exponentiation routine where we know right operand is one word
@@ -274,32 +275,18 @@ package body System.Generic_Bignums is
XY2 : aliased Big_Integer := X ** (Y / 2);
XY2S : aliased Big_Integer :=
Big_Mul (To_Bignum (XY2), To_Bignum (XY2));
- Res : Big_Integer;
begin
Free_Big_Integer (XY2);
- -- Raise storage error if intermediate value is getting too
- -- large, which we arbitrarily define as 200 words for now.
- -- ??? Consider putting a limit instead in a wrapper of
- -- Allocate_Big_Integer and update all calls to
- -- Allocate_Big_Integer to call this wrapper, to catch all such
- -- cases.
-
- if To_Bignum (XY2S).Len > 200 then
- Free_Big_Integer (XY2S);
- raise Storage_Error with
- "exponentiation result is too large";
- end if;
-
- -- Otherwise take care of even/odd cases
-
if (Y and 1) = 0 then
return XY2S;
else
- Res := Big_Mul (To_Bignum (XY2S), X);
- Free_Big_Integer (XY2S);
- return Res;
+ return Res : constant Big_Integer :=
+ Big_Mul (To_Bignum (XY2S), X)
+ do
+ Free_Big_Integer (XY2S);
+ end return;
end if;
end;
end case;
@@ -1108,6 +1095,8 @@ package body System.Generic_Bignums is
-- Normalize --
---------------
+ Bignum_Limit : constant := 200;
+
function Normalize
(X : Digit_Vector;
Neg : Boolean := False) return Big_Integer
@@ -1120,6 +1109,10 @@ package body System.Generic_Bignums is
J := J + 1;
end loop;
+ if X'Last - J > Bignum_Limit then
+ raise Storage_Error with "big integer limit exceeded";
+ end if;
+
return Allocate_Big_Integer (X (J .. X'Last), J <= X'Last and then Neg);
end Normalize;