tree.h (wi::fits_to_tree_p): Accept only 0 and 1 for boolean types.
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 25 Oct 2016 17:11:49 +0000 (17:11 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 25 Oct 2016 17:11:49 +0000 (17:11 +0000)
* tree.h (wi::fits_to_tree_p): Accept only 0 and 1 for boolean types.
* tree.c (int_fits_type_p): Likewise.  Adjust head comment.

From-SVN: r241529

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/opt59.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/opt59_pkg.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/opt59_pkg.ads [new file with mode: 0644]
gcc/testsuite/gnat.dg/opt60.adb [new file with mode: 0644]
gcc/tree.c
gcc/tree.h

index 68ae6878416dfe331cefa40478bc833c934c1f3f..9f1ddc7b56294371b499de539148f798c6d6c1a4 100644 (file)
@@ -1,3 +1,8 @@
+2016-10-25  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * tree.h (wi::fits_to_tree_p): Accept only 0 and 1 for boolean types.
+       * tree.c (int_fits_type_p): Likewise.  Adjust head comment.
+
 2016-10-25  David Malcolm  <dmalcolm@redhat.com>
 
        * ggc-tests.c (forcibly_ggc_collect): Rename to...
index 35b366aeafc208ae7dced4102bacccb2a2deee3a..2dc443193238264f32fc0af85fc3378d636c3939 100644 (file)
@@ -1,3 +1,10 @@
+2016-10-25  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/opt59.adb: New test.
+       * gnat.dg/opt59_pkg.ad[sb]: New helper.
+
+       * gnat.dg/opt60.adb: New test.
+
 2016-10-25  Andre Vehreschild  <vehre@gcc.gnu.org>
 
        PR fortran/72770
diff --git a/gcc/testsuite/gnat.dg/opt59.adb b/gcc/testsuite/gnat.dg/opt59.adb
new file mode 100644 (file)
index 0000000..29665f4
--- /dev/null
@@ -0,0 +1,49 @@
+-- { dg-do run }
+-- { dg-options "-O" }
+
+with Opt59_Pkg; use Opt59_Pkg;
+
+procedure Opt59 is
+
+  type Enum is (Zero, One, Two);
+
+  function Has_True (V : Boolean_Vector) return Boolean is
+  begin
+     for I in V'Range loop
+        if V (I) then
+           return True;
+        end if;
+     end loop;
+     return False;
+  end;
+
+  Data1  : constant Boolean_Vector := Get_BV1;
+  Data2  : constant Boolean_Vector := Get_BV2;
+  Result : Boolean_Vector;
+
+  function F return Enum is
+    Res  : Enum := Zero;
+    Set1 : constant Boolean := Has_True (Data1);
+    Set2 : constant Boolean := Has_True (Data2);
+  begin
+    if Set1 then
+      Res := Two;
+    elsif Set2 then
+      Res := One;
+    end if;
+    return Res;
+  end;
+
+  Val : constant Enum := F;
+
+begin
+
+  for I in Result'Range loop
+    Result (I) := Data1 (I) or Data2 (I);
+  end loop;
+
+  if Val /= Zero then
+    Test (Val = Two);
+  end if;
+
+end;
diff --git a/gcc/testsuite/gnat.dg/opt59_pkg.adb b/gcc/testsuite/gnat.dg/opt59_pkg.adb
new file mode 100644 (file)
index 0000000..16a183b
--- /dev/null
@@ -0,0 +1,20 @@
+package body Opt59_Pkg is
+
+  function Get_BV1 return Boolean_Vector is
+  begin
+    return (others => True);
+  end;
+
+  function Get_BV2 return Boolean_Vector is
+  begin
+    return (others => False);
+  end;
+
+  procedure Test (B : Boolean) is
+  begin
+    if not B then
+      raise Program_Error;
+    end if;
+  end;
+
+end Opt59_Pkg;
diff --git a/gcc/testsuite/gnat.dg/opt59_pkg.ads b/gcc/testsuite/gnat.dg/opt59_pkg.ads
new file mode 100644 (file)
index 0000000..f5628be
--- /dev/null
@@ -0,0 +1,11 @@
+package Opt59_Pkg is
+
+  type Boolean_Vector is array (1 .. 8) of Boolean;
+
+  function Get_BV1 return Boolean_Vector;
+
+  function Get_BV2 return Boolean_Vector;
+
+  procedure Test (B : Boolean);
+
+end Opt59_Pkg;
diff --git a/gcc/testsuite/gnat.dg/opt60.adb b/gcc/testsuite/gnat.dg/opt60.adb
new file mode 100644 (file)
index 0000000..9154fb4
--- /dev/null
@@ -0,0 +1,17 @@
+-- { dg-do compile }
+-- { dg-options "-gnatws -O2 -fdump-tree-optimized" }
+
+with System; use System;
+with System.CRTL; use System.CRTL;
+
+function Opt60 (Size : size_t) return System.Address is
+  Result : System.Address;
+begin
+  Result := malloc (Size);
+  if Result = System.Null_Address then
+    raise Program_Error;
+  end if;
+  return Result;
+end;
+
+-- { dg-final { scan-tree-dump "== 0B" "optimized" } }
index 30d4373a20d625c64da1bb0ee89950b2e143dc9d..56cc653c875466e286dd48dd160cf50093600812 100644 (file)
@@ -9065,8 +9065,8 @@ get_narrower (tree op, int *unsignedp_ptr)
   return win;
 }
 \f
-/* Returns true if integer constant C has a value that is permissible
-   for type TYPE (an INTEGER_TYPE).  */
+/* Return true if integer constant C has a value that is permissible
+   for TYPE, an integral type.  */
 
 bool
 int_fits_type_p (const_tree c, const_tree type)
@@ -9075,6 +9075,11 @@ int_fits_type_p (const_tree c, const_tree type)
   bool ok_for_low_bound, ok_for_high_bound;
   signop sgn_c = TYPE_SIGN (TREE_TYPE (c));
 
+  /* Short-circuit boolean types since various transformations assume that
+     they can only take values 0 and 1.  */
+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+    return integer_zerop (c) || integer_onep (c);
+
 retry:
   type_low_bound = TYPE_MIN_VALUE (type);
   type_high_bound = TYPE_MAX_VALUE (type);
index 9624a01676bef3041b9e462edea63ab9fa180bdf..c494f23c90d44fdbd86837c20e2af8c8f3037498 100644 (file)
@@ -5295,6 +5295,11 @@ template <typename T>
 bool
 wi::fits_to_tree_p (const T &x, const_tree type)
 {
+  /* Short-circuit boolean types since various transformations assume that
+     they can only take values 0 and 1.  */
+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+    return eq_p (x, 0) || eq_p (x, 1);
+
   if (TYPE_SIGN (type) == UNSIGNED)
     return eq_p (x, zext (x, TYPE_PRECISION (type)));
   else