public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Ada] Add centralized capacity check in Generic_Bignums
@ 2020-07-16  9:20 Pierre-Marie de Rodat
  0 siblings, 0 replies; only message in thread
From: Pierre-Marie de Rodat @ 2020-07-16  9:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: Arnaud Charlet

[-- Attachment #1: Type: text/plain, Size: 360 bytes --]

This replaces the special case done in "**" so far.

Tested on x86_64-pc-linux-gnu, committed on trunk

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.

[-- Attachment #2: patch.diff --]
[-- Type: text/x-diff, Size: 2669 bytes --]

diff --git a/gcc/ada/libgnat/s-genbig.adb b/gcc/ada/libgnat/s-genbig.adb
--- 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;
 



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-07-16  9:20 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-16  9:20 [Ada] Add centralized capacity check in Generic_Bignums Pierre-Marie de Rodat

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).