fold-const.c (build_range_check): Properly deal with enumeral and boolean base types.
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 12 Apr 2009 21:39:39 +0000 (21:39 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 12 Apr 2009 21:39:39 +0000 (21:39 +0000)
* fold-const.c (build_range_check): Properly deal with enumeral and
boolean base types.

From-SVN: r145988

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

index 8b1a41a99db4cf07daf518d907045e6ad59dae85..22204cb7224797e202bb8f1ce82dc522766910a8 100644 (file)
@@ -1,3 +1,8 @@
+2009-04-12 Eric Botcazou <ebotcazou@adacore.com>
+
+       * fold-const.c (build_range_check): Properly deal with enumeral and
+       boolean base types.
+
 2009-04-12  Steven Bosscher  <steven@gcc.gnu.org>
 
        * doc/invoke.texi (max_gcse_passes): Remove documentation.
index dd2f62d4a4b4b44ab4b2387ae876cdb438c91205..bd5e97df4a92b622ae27c6620ee500b197ecf6d1 100644 (file)
@@ -4671,8 +4671,8 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh,
 static tree
 build_range_check (tree type, tree exp, int in_p, tree low, tree high)
 {
-  tree etype = TREE_TYPE (exp);
-  tree value;
+  tree etype = TREE_TYPE (exp), value;
+  enum tree_code code;
 
 #ifdef HAVE_canonicalize_funcptr_for_compare
   /* Disable this optimization for function pointer expressions
@@ -4756,20 +4756,25 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high)
 
   /* Optimize (c>=low) && (c<=high) into (c-low>=0) && (c-low<=high-low).
      This requires wrap-around arithmetics for the type of the expression.  */
-  switch (TREE_CODE (etype))
+  code = TREE_CODE (etype);
+  switch (code)
     {
     case INTEGER_TYPE:
+    case ENUMERAL_TYPE:
+    case BOOLEAN_TYPE:
       /* There is no requirement that LOW be within the range of ETYPE
         if the latter is a subtype.  It must, however, be within the base
         type of ETYPE.  So be sure we do the subtraction in that type.  */
-      if (TREE_TYPE (etype))
-       etype = TREE_TYPE (etype);
-      break;
+      if (code == INTEGER_TYPE && TREE_TYPE (etype))
+       {
+         etype = TREE_TYPE (etype);
+         /* But not in an enumeral or boolean type though.  */
+         code = TREE_CODE (etype);
+       }
 
-    case ENUMERAL_TYPE:
-    case BOOLEAN_TYPE:
-      etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
-                                             TYPE_UNSIGNED (etype));
+      if (code != INTEGER_TYPE)
+       etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
+                                               TYPE_UNSIGNED (etype));
       break;
 
     default:
index a4452b375660200ad611678481c423610b7acd9d..876431a6b754b60b72d2656891aa66d6bc570464 100644 (file)
@@ -1,4 +1,9 @@
-009-04-12  Uros Bizjak  <ubizjak@gmail.com>
+2009-04-12  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/enum1.adb: New test.
+       * gnat.dg/enum1_pkg.ads: New helper.
+
+2009-04-12  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/39740
        * gcc.target/alpha/pr39740.c: New test.
diff --git a/gcc/testsuite/gnat.dg/enum1.adb b/gcc/testsuite/gnat.dg/enum1.adb
new file mode 100644 (file)
index 0000000..f751d24
--- /dev/null
@@ -0,0 +1,17 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Enum1_Pkg; use Enum1_Pkg;
+
+procedure Enum1 is
+
+  function Cond return Boolean is
+  begin
+    return My_N = Two or My_N = Three;
+  end;
+
+begin
+  if Cond then
+    raise Constraint_Error;
+  end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/enum1_pkg.ads b/gcc/testsuite/gnat.dg/enum1_pkg.ads
new file mode 100644 (file)
index 0000000..ff09086
--- /dev/null
@@ -0,0 +1,9 @@
+package Enum1_Pkg is
+
+  type Enum is (One, Two, Three);
+
+  subtype Sub_Enum is Enum;
+
+  My_N : Sub_Enum := One;
+
+end Enum1_Pkg;