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,
