From: Eric Botcazou <[email protected]>
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.
Tested on x86_64-pc-linux-gnu, committed on master.
---
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 8759099c193..1107af3e003 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,
--
2.51.0