From 5815f92a08bb7e03c83e3592e93ea2470067148c Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Wed, 18 Dec 2019 07:15:52 +0000 Subject: [PATCH] [Ada] Simplify Big_Integer and Big_Real interface 2019-12-18 Arnaud Charlet gcc/ada/ * libgnat/a-nbnbin.ads, libgnat/a-nbnbin.adb, libgnat/a-nbnbre.ads, libgnat/a-nbnbre.adb: Replace Optional_Big_* types by a simple check and exception raise in Get_Bignum. (Set_Bignum): Arg should be 'out' and not 'in out'. (Invalid_Big_Integer, No_Big_Real): Removed. (Is_Valid): Now convention Intrinsic. From-SVN: r279515 --- gcc/ada/ChangeLog | 10 +++++ gcc/ada/libgnat/a-nbnbin.adb | 71 ++++++++++++++++++++---------------- gcc/ada/libgnat/a-nbnbin.ads | 29 +++------------ gcc/ada/libgnat/a-nbnbre.adb | 27 +++++--------- gcc/ada/libgnat/a-nbnbre.ads | 20 +++------- 5 files changed, 70 insertions(+), 87 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 90d25c022c9..94d115e5852 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,13 @@ +2019-12-18 Arnaud Charlet + + * libgnat/a-nbnbin.ads, libgnat/a-nbnbin.adb, + libgnat/a-nbnbre.ads, libgnat/a-nbnbre.adb: Replace + Optional_Big_* types by a simple check and exception raise in + Get_Bignum. + (Set_Bignum): Arg should be 'out' and not 'in out'. + (Invalid_Big_Integer, No_Big_Real): Removed. + (Is_Valid): Now convention Intrinsic. + 2019-12-18 Piotr Trojanek * doc/gnat_rm/implementation_defined_pragmas.rst, diff --git a/gcc/ada/libgnat/a-nbnbin.adb b/gcc/ada/libgnat/a-nbnbin.adb index 1c066f3a31e..7d8311d165e 100644 --- a/gcc/ada/libgnat/a-nbnbin.adb +++ b/gcc/ada/libgnat/a-nbnbin.adb @@ -44,11 +44,14 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is procedure Free is new Ada.Unchecked_Deallocation (Bignum_Data, Bignum); - function Get_Bignum (Arg : Optional_Big_Integer) return Bignum is - (To_Bignum (Arg.Value.C)); - -- Return the Bignum value stored in Arg - - procedure Set_Bignum (Arg : in out Optional_Big_Integer; Value : Bignum) + function Get_Bignum (Arg : Big_Integer) return Bignum is + (if Arg.Value.C = System.Null_Address + then raise Constraint_Error with "invalid big integer" + else To_Bignum (Arg.Value.C)); + -- Check for validity of Arg and return the Bignum value stored in Arg. + -- Raise Constraint_Error if Arg is uninitialized. + + procedure Set_Bignum (Arg : out Big_Integer; Value : Bignum) with Inline; -- Set the Bignum value stored in Arg to Value @@ -56,7 +59,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is -- Set_Bignum -- ---------------- - procedure Set_Bignum (Arg : in out Optional_Big_Integer; Value : Bignum) is + procedure Set_Bignum (Arg : out Big_Integer; Value : Bignum) is begin Arg.Value.C := To_Address (Value); end Set_Bignum; @@ -65,16 +68,9 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is -- Is_Valid -- -------------- - function Is_Valid (Arg : Optional_Big_Integer) return Boolean is + function Is_Valid (Arg : Big_Integer) return Boolean is (Arg.Value.C /= System.Null_Address); - -------------------------- - -- Invalid_Big_Integer -- - -------------------------- - - function Invalid_Big_Integer return Optional_Big_Integer is - (Value => (Ada.Finalization.Controlled with C => System.Null_Address)); - --------- -- "=" -- --------- @@ -125,7 +121,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is -------------------- function To_Big_Integer (Arg : Integer) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, To_Bignum (Long_Long_Integer (Arg))); return Result; @@ -151,7 +147,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is -------------------- function To_Big_Integer (Arg : Int) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, To_Bignum (Long_Long_Integer (Arg))); return Result; @@ -179,7 +175,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is -------------------- function To_Big_Integer (Arg : Int) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, To_Bignum (Unsigned_64 (Arg))); return Result; @@ -283,7 +279,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ----------------- function From_String (Arg : String) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin -- ??? only support Long_Long_Integer, good enough for now Set_Bignum (Result, To_Bignum (Long_Long_Integer'Value (Arg))); @@ -306,7 +302,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is --------- function "+" (L : Big_Integer) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, new Bignum_Data'(Get_Bignum (L).all)); return Result; @@ -317,7 +313,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is --------- function "-" (L : Big_Integer) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, Big_Neg (Get_Bignum (L))); return Result; @@ -328,7 +324,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ----------- function "abs" (L : Big_Integer) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, Big_Abs (Get_Bignum (L))); return Result; @@ -339,7 +335,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is --------- function "+" (L, R : Big_Integer) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, Big_Add (Get_Bignum (L), Get_Bignum (R))); return Result; @@ -350,7 +346,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is --------- function "-" (L, R : Big_Integer) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, Big_Sub (Get_Bignum (L), Get_Bignum (R))); return Result; @@ -361,7 +357,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is --------- function "*" (L, R : Big_Integer) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, Big_Mul (Get_Bignum (L), Get_Bignum (R))); return Result; @@ -372,7 +368,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is --------- function "/" (L, R : Big_Integer) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, Big_Div (Get_Bignum (L), Get_Bignum (R))); return Result; @@ -383,7 +379,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ----------- function "mod" (L, R : Big_Integer) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, Big_Mod (Get_Bignum (L), Get_Bignum (R))); return Result; @@ -394,7 +390,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ----------- function "rem" (L, R : Big_Integer) return Big_Integer is - Result : Optional_Big_Integer; + Result : Big_Integer; begin Set_Bignum (Result, Big_Rem (Get_Bignum (L), Get_Bignum (R))); return Result; @@ -405,12 +401,23 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ---------- function "**" (L : Big_Integer; R : Natural) return Big_Integer is - Exp : Bignum := To_Bignum (Long_Long_Integer (R)); - Result : Optional_Big_Integer; begin - Set_Bignum (Result, Big_Exp (Get_Bignum (L), Exp)); - Free (Exp); - return Result; + -- Explicitly check for validity before allocating Exp so that + -- the call to Get_Bignum below cannot raise an exception before + -- we get a chance to free Exp. + + if not Is_Valid (L) then + raise Constraint_Error with "invalid big integer"; + end if; + + declare + Exp : Bignum := To_Bignum (Long_Long_Integer (R)); + Result : Big_Integer; + begin + Set_Bignum (Result, Big_Exp (Get_Bignum (L), Exp)); + Free (Exp); + return Result; + end; end "**"; --------- diff --git a/gcc/ada/libgnat/a-nbnbin.ads b/gcc/ada/libgnat/a-nbnbin.ads index 52f01ea8e63..a54b09f6ab9 100644 --- a/gcc/ada/libgnat/a-nbnbin.ads +++ b/gcc/ada/libgnat/a-nbnbin.ads @@ -25,19 +25,12 @@ package Ada.Numerics.Big_Numbers.Big_Integers with Preelaborate -- Nonblocking is - type Optional_Big_Integer is private - with Default_Initial_Condition => not Is_Valid (Optional_Big_Integer); - -- Integer_Literal => From_String, + type Big_Integer is private; + -- with Integer_Literal => From_String, -- Put_Image => Put_Image; - function Is_Valid (Arg : Optional_Big_Integer) return Boolean; - - subtype Big_Integer is Optional_Big_Integer - with Dynamic_Predicate => Is_Valid (Big_Integer), - Predicate_Failure => (raise Constraint_Error); - - function Invalid_Big_Integer return Optional_Big_Integer - with Post => not Is_Valid (Invalid_Big_Integer'Result); + function Is_Valid (Arg : Big_Integer) return Boolean + with Convention => Intrinsic; function "=" (L, R : Big_Integer) return Boolean; @@ -51,18 +44,6 @@ is function To_Big_Integer (Arg : Integer) return Big_Integer; - subtype Optional_Big_Positive is Optional_Big_Integer - with Dynamic_Predicate => - (not Is_Valid (Optional_Big_Positive)) - or else (Optional_Big_Positive > To_Big_Integer (0)), - Predicate_Failure => (raise Constraint_Error); - - subtype Optional_Big_Natural is Optional_Big_Integer - with Dynamic_Predicate => - (not Is_Valid (Optional_Big_Natural)) - or else (Optional_Big_Natural >= To_Big_Integer (0)), - Predicate_Failure => (raise Constraint_Error); - subtype Big_Positive is Big_Integer with Dynamic_Predicate => Big_Positive > To_Big_Integer (0), Predicate_Failure => (raise Constraint_Error); @@ -157,7 +138,7 @@ private procedure Adjust (This : in out Controlled_Bignum); procedure Finalize (This : in out Controlled_Bignum); - type Optional_Big_Integer is record + type Big_Integer is record Value : Controlled_Bignum; end record; diff --git a/gcc/ada/libgnat/a-nbnbre.adb b/gcc/ada/libgnat/a-nbnbre.adb index 8cb0f63e713..c087f4960cc 100644 --- a/gcc/ada/libgnat/a-nbnbre.adb +++ b/gcc/ada/libgnat/a-nbnbre.adb @@ -45,22 +45,15 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is -- Is_Valid -- -------------- - function Is_Valid (Arg : Optional_Big_Real) return Boolean is + function Is_Valid (Arg : Big_Real) return Boolean is (Is_Valid (Arg.Num) and then Is_Valid (Arg.Den)); - ----------------- - -- No_Big_Real -- - ----------------- - - function No_Big_Real return Optional_Big_Real is - (Num => Invalid_Big_Integer, Den => Invalid_Big_Integer); - --------- -- "/" -- --------- function "/" (Num, Den : Big_Integer) return Big_Real is - Result : Optional_Big_Real; + Result : Big_Real; begin if Den = To_Big_Integer (0) then raise Constraint_Error with "divide by zero"; @@ -323,7 +316,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is function From_String (Arg : String) return Big_Real is Ten : constant Big_Integer := To_Big_Integer (10); - Frac : Optional_Big_Integer; + Frac : Big_Integer; Exp : Integer := 0; Pow : Natural := 0; Index : Natural := 0; @@ -353,7 +346,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is end if; declare - Result : Optional_Big_Real; + Result : Big_Real; begin Result.Den := Ten ** Pow; Result.Num := From_String (Arg (Arg'First .. Index)) * Result.Den; @@ -414,7 +407,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is --------- function "+" (L : Big_Real) return Big_Real is - Result : Optional_Big_Real; + Result : Big_Real; begin Result.Num := L.Num; Result.Den := L.Den; @@ -440,7 +433,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is --------- function "+" (L, R : Big_Real) return Big_Real is - Result : Optional_Big_Real; + Result : Big_Real; begin Result.Num := L.Num * R.Den + R.Num * L.Den; Result.Den := L.Den * R.Den; @@ -453,7 +446,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is --------- function "-" (L, R : Big_Real) return Big_Real is - Result : Optional_Big_Real; + Result : Big_Real; begin Result.Num := L.Num * R.Den - R.Num * L.Den; Result.Den := L.Den * R.Den; @@ -466,7 +459,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is --------- function "*" (L, R : Big_Real) return Big_Real is - Result : Optional_Big_Real; + Result : Big_Real; begin Result.Num := L.Num * R.Num; Result.Den := L.Den * R.Den; @@ -479,7 +472,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is --------- function "/" (L, R : Big_Real) return Big_Real is - Result : Optional_Big_Real; + Result : Big_Real; begin Result.Num := L.Num * R.Den; Result.Den := L.Den * R.Num; @@ -492,7 +485,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is ---------- function "**" (L : Big_Real; R : Integer) return Big_Real is - Result : Optional_Big_Real; + Result : Big_Real; begin if R = 0 then Result.Num := To_Big_Integer (1); diff --git a/gcc/ada/libgnat/a-nbnbre.ads b/gcc/ada/libgnat/a-nbnbre.ads index 07e9173fd78..4827caae3e3 100644 --- a/gcc/ada/libgnat/a-nbnbre.ads +++ b/gcc/ada/libgnat/a-nbnbre.ads @@ -23,19 +23,11 @@ package Ada.Numerics.Big_Numbers.Big_Reals with Preelaborate -- Nonblocking, Global => in out synchronized Big_Reals is - type Optional_Big_Real is private with - Default_Initial_Condition => not Is_Valid (Optional_Big_Real); --- Real_Literal => From_String, --- Put_Image => Put_Image; + type Big_Real is private; +-- with Real_Literal => From_String, +-- Put_Image => Put_Image; - function Is_Valid (Arg : Optional_Big_Real) return Boolean; - - function No_Big_Real return Optional_Big_Real - with Post => not Is_Valid (No_Big_Real'Result); - - subtype Big_Real is Optional_Big_Real - with Dynamic_Predicate => Is_Valid (Big_Real), - Predicate_Failure => (raise Constraint_Error); + function Is_Valid (Arg : Big_Real) return Boolean; function "/" (Num, Den : Big_Integers.Big_Integer) return Big_Real; -- with Pre => (if Big_Integers."=" (Den, Big_Integers.To_Big_Integer (0)) @@ -139,8 +131,8 @@ is private - type Optional_Big_Real is record - Num, Den : Big_Integers.Optional_Big_Integer; + type Big_Real is record + Num, Den : Big_Integers.Big_Integer; end record; end Ada.Numerics.Big_Numbers.Big_Reals; -- 2.30.2