]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Fix spurious Constraint_Error raised by 'Value of fixed-point types
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 3 Jun 2025 16:54:03 +0000 (18:54 +0200)
committerMarc Poulhiès <dkm@gcc.gnu.org>
Thu, 3 Jul 2025 08:16:22 +0000 (10:16 +0200)
This happens for very large Smalls with regard to the size of the mantissa,
because the prerequisites of the implementation used in this case are not
met, although they are documented in the head comment of Integer_To_Fixed.

This change documents them at the beginning of the body of System.Value_F
and adjusts the compiler interface accordingly.

gcc/ada/ChangeLog:

* libgnat/s-valuef.adb: Document the prerequisites more precisely.
* libgnat/a-tifiio.adb (OK_Get_32): Adjust to the prerequisites.
(OK_Get_64): Likewise.
* libgnat/a-tifiio__128.adb (OK_Get_32): Likewise.
(OK_Get_64): Likewise.
(OK_Get_128): Likewise.
* libgnat/a-wtfiio.adb (OK_Get_32): Likewise.
(OK_Get_64): Likewise.
* libgnat/a-wtfiio__128.adb (OK_Get_32): Likewise.
(OK_Get_64): Likewise.
(OK_Get_128): Likewise.
* libgnat/a-ztfiio.adb (OK_Get_32): Likewise.
(OK_Get_64): Likewise.
* libgnat/a-ztfiio__128.adb (OK_Get_32): Likewise.
(OK_Get_64): Likewise.
(OK_Get_128): Likewise.
* exp_imgv.adb (Expand_Value_Attribute): Adjust the conditions under
which the RE_Value_Fixed{32,64,128} routines are called for ordinary
fixed-point types.

gcc/ada/exp_imgv.adb
gcc/ada/libgnat/a-tifiio.adb
gcc/ada/libgnat/a-tifiio__128.adb
gcc/ada/libgnat/a-wtfiio.adb
gcc/ada/libgnat/a-wtfiio__128.adb
gcc/ada/libgnat/a-ztfiio.adb
gcc/ada/libgnat/a-ztfiio__128.adb
gcc/ada/libgnat/s-valuef.adb

index c7cf06ba444f5ae61f621c2f6a0d05af8a26f792..6c2b940736baca9fd4b1e51085f5e197958958fa 100644 (file)
@@ -1640,23 +1640,22 @@ package body Exp_Imgv is
             Num : constant Uint := Norm_Num (Small_Value (Rtyp));
             Den : constant Uint := Norm_Den (Small_Value (Rtyp));
             Max : constant Uint := UI_Max (Num, Den);
-            Min : constant Uint := UI_Min (Num, Den);
             Siz : constant Uint := Esize (Rtyp);
 
          begin
             if Siz <= 32
               and then Max <= Uint_2 ** 31
-              and then (Min = Uint_1 or else Max <= Uint_2 ** 27)
+              and then (Num = Uint_1 or else Max <= Uint_2 ** 27)
             then
                Vid := RE_Value_Fixed32;
             elsif Siz <= 64
               and then Max <= Uint_2 ** 63
-              and then (Min = Uint_1 or else Max <= Uint_2 ** 59)
+              and then (Num = Uint_1 or else Max <= Uint_2 ** 59)
             then
                Vid := RE_Value_Fixed64;
             elsif System_Max_Integer_Size = 128
               and then Max <= Uint_2 ** 127
-              and then (Min = Uint_1 or else Max <= Uint_2 ** 123)
+              and then (Num = Uint_1 or else Max <= Uint_2 ** 123)
             then
                Vid := RE_Value_Fixed128;
             else
index 735859c3f15052318108b04975818722e06de694..26f04ed726ee2e7eddad0d2b7dde7cc1b33c6000 100644 (file)
@@ -194,9 +194,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -223,9 +220,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
index 7424346fe3d62091061d20d453af533d4226d349..78c25f29bc8b8eaac6485504e5fd081a5f441bff 100644 (file)
@@ -201,9 +201,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -230,9 +227,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -259,9 +253,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**127)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**127)
-           or else
           (Num'Base'Small_Numerator <= 2**123
             and then Num'Base'Small_Denominator <= 2**123));
    --  These conditions are derived from the prerequisites of System.Value_F
index ed69d65df09dacd9b58993f805362ff82306b88a..3ceda12b9ec31cd7b92d975f5ef5782b835c6790 100644 (file)
@@ -73,9 +73,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -102,9 +99,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
index ec8deca6ca4e84e8db623fc52f999f60d679de5a..8757ffb2514983fb2e1aca44f32eb90d29a3c37f 100644 (file)
@@ -80,9 +80,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -109,9 +106,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -138,9 +132,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**127)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**127)
-           or else
           (Num'Base'Small_Numerator <= 2**123
             and then Num'Base'Small_Denominator <= 2**123));
    --  These conditions are derived from the prerequisites of System.Value_F
index edf58ad85eadf76a6c8ab41a3ae3f998c572fd3a..b9f4f43226f0101dfa4409983732386bef6b25db 100644 (file)
@@ -73,9 +73,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -102,9 +99,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
index bc0062f9d9f86edbc26ef8e003ebf65411075dd4..eb02a4a2ceceb384ec0550dc5b9cd9b6ee836609 100644 (file)
@@ -81,9 +81,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -110,9 +107,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -139,9 +133,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**127)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**127)
-           or else
           (Num'Base'Small_Numerator <= 2**123
             and then Num'Base'Small_Denominator <= 2**123));
    --  These conditions are derived from the prerequisites of System.Value_F
index 1743749f542165c19c5984d1a51403225f0f6939..f38f2cc66ac3ef4366fa509ed9cc424f1eeb0af7 100644 (file)
@@ -36,12 +36,13 @@ with System.Value_R;
 package body System.Value_F is
 
    --  The prerequisite of the implementation is that the computation of the
-   --  operands of the scaled divide does not unduly overflow when the small
-   --  is neither an integer nor the reciprocal of an integer, which means
-   --  that its numerator and denominator must be both not larger than the
-   --  smallest divide 2**(Int'Size - 1) / Base where Base ranges over the
-   --  supported values for the base of the literal. Given that the largest
-   --  supported base is 16, this gives a limit of 2**(Int'Size - 5).
+   --  operands of the scaled divide does not unduly overflow, which means
+   --  that the numerator and the denominator of the small must be both not
+   --  larger than the smallest divide 2**(Int'Size - 1) / Base where Base
+   --  ranges over the supported values for the base of the literal, except
+   --  when the numerator is 1, in which case up to 2**(Int'Size - 1) is
+   --  permitted for the denominator. Given that the largest supported base
+   --  is 16, this gives a limit of 2**(Int'Size - 5) in the general case.
 
    pragma Assert (Int'Size <= Uns'Size);
    --  We need an unsigned type large enough to represent the mantissa
@@ -135,6 +136,9 @@ package body System.Value_F is
    --    Num * (Base ** -ScaleB) <= Num * (B ** N) < Den * B
 
    --  which means that the product does not overflow if Den <= 2**(M-1) / B.
+   --  Moreover, if 2**(M-1) / B < Den <= 2**(M-1), we can add 1 to ScaleB and
+   --  divide Val by B while preserving the rightmost B-digit of Val in Extra2
+   --  without changing the computation when Num = 1.
 
    ----------------------
    -- Integer_To_Fixed --