File nvl623386.patch of Package gcc43
2010-08-26 Richard Guenther <rguenther@suse.de>
* tree-ssa-copyrename.c (copy_rename_partition_coalesce): Do not
coalesce different types.
* g++.dg/torture/20100825.C: New testcase.
Index: gcc/tree-ssa-copyrename.c
===================================================================
--- gcc/tree-ssa-copyrename.c.orig 2011-01-21 12:26:07.000000000 +0100
+++ gcc/tree-ssa-copyrename.c 2011-01-21 12:27:22.000000000 +0100
@@ -239,7 +239,12 @@ copy_rename_partition_coalesce (var_map
}
/* Don't coalesce if the two variables aren't type compatible. */
- if (!types_compatible_p (TREE_TYPE (root1), TREE_TYPE (root2)))
+ if (!types_compatible_p (TREE_TYPE (root1), TREE_TYPE (root2))
+ /* There is a disconnect between the middle-end type-system and
+ VRP, avoid coalescing enum types with different bounds. */
+ || ((TREE_CODE (TREE_TYPE (root1)) == ENUMERAL_TYPE
+ || TREE_CODE (TREE_TYPE (root2)) == ENUMERAL_TYPE)
+ && TREE_TYPE (root1) != TREE_TYPE (root2)))
{
if (debug)
fprintf (debug, " : Incompatible types. No coalesce.\n");
Index: gcc/testsuite/g++.dg/torture/20100825.C
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/g++.dg/torture/20100825.C 2011-01-21 12:26:26.000000000 +0100
@@ -0,0 +1,15 @@
+// { dg-do run }
+
+typedef enum { zero = 0, one = 1, two = 2, ENUM_MAX = 3 } my_enum;
+my_enum e;
+extern "C" void abort (void);
+int __attribute__((noinline)) foo() { return 10; }
+int main()
+{
+ int r;
+ r = foo();
+ if ((r < 0) || (r >= ENUM_MAX))
+ return 0;
+ e = (my_enum)r;
+ abort ();
+}