[Ada] Conversion of arithmetic expression to wider type flagged as redundant

Submitted by Arnaud Charlet on Sept. 9, 2010, 1:44 p.m.

Details

Message ID 20100909134449.GA19747@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Sept. 9, 2010, 1:44 p.m.
In certain cases, the compiler converts the operands of an arithmetic
expression that is an argument of a conversion to a wider type, to
avoid generation of an overflow check. This can result in the conversion
being wrongly flagged as redundant. By rewriting the operator node, so
that the original node will be retained, the test for redundant conversions
properly recognizes that the conversion in the source was not redundant.

The following test must compile quietly with -gnatwae:

package Nonredundant_Conversion is

   type Unsigned_64 is mod 2 ** 64;

   Nat : Natural;

   Uns : Unsigned_64 := Unsigned_64 (Nat + 1);

end Nonredundant_Conversion;

Tested on x86_64-pc-linux-gnu, committed on trunk

2010-09-09  Gary Dismukes  <dismukes@adacore.com>

	* checks.adb (Apply_Arithmetic_Overflow_Check): When converting the
	operands of an operator to the type of an enclosing conversion, rewrite
	the operator so the conversion can't be flagged as redundant.
	Remove useless assignments to Typ and Rtyp.

Patch hide | download patch | download mbox

Index: checks.adb
===================================================================
--- checks.adb	(revision 164000)
+++ checks.adb	(working copy)
@@ -722,8 +722,8 @@  package body Checks is
 
    procedure Apply_Arithmetic_Overflow_Check (N : Node_Id) is
       Loc   : constant Source_Ptr := Sloc (N);
-      Typ   : Entity_Id           := Etype (N);
-      Rtyp  : Entity_Id           := Root_Type (Typ);
+      Typ   : constant Entity_Id  := Etype (N);
+      Rtyp  : constant Entity_Id  := Root_Type (Typ);
 
    begin
       --  An interesting special case. If the arithmetic operation appears as
@@ -815,9 +815,14 @@  package body Checks is
                         Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
                         Expression   => Relocate_Node (Right_Opnd (N))));
 
+                     --  Rewrite the conversion operand so that the original
+                     --  node is retained, in order to avoid the warning for
+                     --  redundant conversions in Resolve_Type_Conversion.
+
+                     Rewrite (N, Relocate_Node (N));
+
                      Set_Etype (N, Target_Type);
-                     Typ := Target_Type;
-                     Rtyp := Root_Type (Typ);
+
                      Analyze_And_Resolve (Left_Opnd  (N), Target_Type);
                      Analyze_And_Resolve (Right_Opnd (N), Target_Type);