https://gcc.gnu.org/g:f714e1baf8804dfcff5bf9f23cd548c2c2e32a40

commit r16-4687-gf714e1baf8804dfcff5bf9f23cd548c2c2e32a40
Author: Eric Botcazou <[email protected]>
Date:   Fri Sep 26 19:45:10 2025 +0200

    ada: Fix unexpected overflow check before fixed-point multiplication
    
    The problem is that the code generating the fixed-point multiply uses the
    subtypes of the operands to size the operation, while operations are to be
    performed in base types, which are signed per the RM 3.5.9(12) subclause.
    As a consequence, when the subtypes are fully asymmetric unsigned, the size
    is too small and an incorrect overflow check is generated.
    
    The code generating the divide was fixed a long time ago, this aligns the
    code generating the multiply and the code generating the remainder, which
    in turn requires a couple of adjustments to related routines.
    
    gcc/ada/ChangeLog:
    
            PR ada/122063
            * exp_fixd.adb (Build_Double_Divide_Code): Convert the result of the
            multiply.
            (Build_Multiply): Use base types of operands to size the operation.
            (Build_Rem): Likewise.
            (Build_Scaled_Divide_Code): Convert the result of the multiply.

Diff:
---
 gcc/ada/exp_fixd.adb | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/gcc/ada/exp_fixd.adb b/gcc/ada/exp_fixd.adb
index 8759099c193e..1107af3e003f 100644
--- a/gcc/ada/exp_fixd.adb
+++ b/gcc/ada/exp_fixd.adb
@@ -595,7 +595,8 @@ package body Exp_Fixd is
              Defining_Identifier => Dnn,
              Object_Definition   => New_Occurrence_Of (QR_Typ, Loc),
              Constant_Present    => True,
-             Expression          => Build_Multiply (N, Y, Z)));
+             Expression          =>
+               Build_Conversion (N, QR_Typ, Build_Multiply (N, Y, Z))));
 
          Quo :=
            Build_Divide (N,
@@ -656,8 +657,8 @@ package body Exp_Fixd is
 
    function Build_Multiply (N : Node_Id; L, R : Node_Id) return Node_Id is
       Loc         : constant Source_Ptr := Sloc (N);
-      Left_Type   : constant Entity_Id  := Etype (L);
-      Right_Type  : constant Entity_Id  := Etype (R);
+      Left_Type   : constant Entity_Id  := Base_Type (Etype (L));
+      Right_Type  : constant Entity_Id  := Base_Type (Etype (R));
       Left_Size   : Int;
       Right_Size  : Int;
       Result_Type : Entity_Id;
@@ -746,8 +747,8 @@ package body Exp_Fixd is
 
    function Build_Rem (N : Node_Id; L, R : Node_Id) return Node_Id is
       Loc         : constant Source_Ptr := Sloc (N);
-      Left_Type   : constant Entity_Id  := Etype (L);
-      Right_Type  : constant Entity_Id  := Etype (R);
+      Left_Type   : constant Entity_Id  := Base_Type (Etype (L));
+      Right_Type  : constant Entity_Id  := Base_Type (Etype (R));
       Result_Type : Entity_Id;
       Rnode       : Node_Id;
 
@@ -959,7 +960,8 @@ package body Exp_Fixd is
              Defining_Identifier => Nnn,
              Object_Definition   => New_Occurrence_Of (QR_Typ, Loc),
              Constant_Present    => True,
-             Expression          => Build_Multiply (N, X, Y)),
+             Expression          =>
+               Build_Conversion (N, QR_Typ, Build_Multiply (N, X, Y))),
 
            Make_Object_Declaration (Loc,
              Defining_Identifier => Dnn,

Reply via email to