re PR middle-end/49189 (infinite recursion in constant folder)
authorRichard Guenther <rguenther@suse.de>
Fri, 27 May 2011 13:13:28 +0000 (13:13 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 27 May 2011 13:13:28 +0000 (13:13 +0000)
2011-05-27  Richard Guenther  <rguenther@suse.de>

PR middle-end/49189
* fold-const.c (fold_unary_loc): Do not re-fold folding conversions
of comparisons.

* gnat.dg/bit_packed_array5.adb: New testcase.
* gnat.dg/bit_packed_array5.ads: Likewise.

From-SVN: r174330

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/bit_packed_array5.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/bit_packed_array5.ads [new file with mode: 0644]

index 957443583c8742807e0546c62545c718ba752d4f..6271933bd1347db4e475f165ffb4a6de8e4eb50c 100644 (file)
@@ -1,3 +1,9 @@
+2011-05-27  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/49189
+       * fold-const.c (fold_unary_loc): Do not re-fold folding conversions
+       of comparisons.
+
 2011-05-27  Bernd Schmidt  <bernds@codesourcery.com>
 
        * haifa-sched.c (sched_scan_info): Remove.
index ebb1d34d5f4cd7aa210ffdc218b1421a8d436ac8..9a3f8cb0fecf5c0c788b0388ad9fdac286675fdf 100644 (file)
@@ -7660,15 +7660,19 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
       if (COMPARISON_CLASS_P (op0))
        {
          /* If we have (type) (a CMP b) and type is an integral type, return
-            new expression involving the new type.  */
+            new expression involving the new type.  Canonicalize
+            (type) (a CMP b) to (a CMP b) ? (type) true : (type) false for
+            non-integral type.
+            Do not fold the result as that would not simplify further, also
+            folding again results in recursions.  */
          if (INTEGRAL_TYPE_P (type))
-           return fold_build2_loc (loc, TREE_CODE (op0), type,
-                                   TREE_OPERAND (op0, 0),
-                                   TREE_OPERAND (op0, 1));
+           return build2_loc (loc, TREE_CODE (op0), type,
+                              TREE_OPERAND (op0, 0),
+                              TREE_OPERAND (op0, 1));
          else
-           return fold_build3_loc (loc, COND_EXPR, type, op0,
-                                   fold_convert (type, boolean_true_node),
-                                   fold_convert (type, boolean_false_node));
+           return build3_loc (loc, COND_EXPR, type, op0,
+                              fold_convert (type, boolean_true_node),
+                              fold_convert (type, boolean_false_node));
        }
 
       /* Handle cases of two conversions in a row.  */
index a6ce74b472aaa568b396310be6233a365313b618..2bf68b3da0672cbda3e2e8c14ef04c5849ed2e4f 100644 (file)
@@ -1,3 +1,9 @@
+2011-05-27  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/49189
+       * gnat.dg/bit_packed_array5.adb: New testcase.
+       * gnat.dg/bit_packed_array5.ads: Likewise.
+
 2011-05-26  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/cpp0x/friend1.C: New.
diff --git a/gcc/testsuite/gnat.dg/bit_packed_array5.adb b/gcc/testsuite/gnat.dg/bit_packed_array5.adb
new file mode 100644 (file)
index 0000000..de574fb
--- /dev/null
@@ -0,0 +1,21 @@
+with System;
+
+package body Bit_Packed_Array5 is
+
+   function Inv (Word : Word_Type) return Word_Type is
+      W : Word_Type := Word;
+      pragma Volatile (W);
+
+      A_W : constant System.Address := W'Address;
+
+      V : Short_Bit_Array_Type;
+      for V'Address use A_W;
+      pragma Volatile (V);
+   begin
+      for I in V'Range loop
+          V (I) := not V (I);
+      end loop;
+      return W;
+   end;
+
+end Bit_Packed_Array5;
diff --git a/gcc/testsuite/gnat.dg/bit_packed_array5.ads b/gcc/testsuite/gnat.dg/bit_packed_array5.ads
new file mode 100644 (file)
index 0000000..8d335f0
--- /dev/null
@@ -0,0 +1,16 @@
+-- { dg-do compile }
+
+package Bit_Packed_Array5 is
+
+   type Bit_Array is array (Integer range <>) of Boolean;
+   pragma Pack (Bit_Array);
+
+   type Short_Bit_Array_Type is new Bit_Array (0 .. 15);
+   for Short_Bit_Array_Type'Size use 16;
+
+   type Word_Type is range 0 .. 65535;
+   for Word_Type'Size use 16;
+
+   function Inv (Word : Word_Type) return Word_Type;
+
+end Bit_Packed_Array5;