utils.c (unchecked_convert): When the result type is a non-biased integral type with...
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 5 Sep 2017 09:12:07 +0000 (09:12 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 5 Sep 2017 09:12:07 +0000 (09:12 +0000)
* gcc-interface/utils.c (unchecked_convert): When the result type is a
non-biased integral type with size 0, set the result to 0 directly.

From-SVN: r251701

gcc/ada/ChangeLog
gcc/ada/gcc-interface/utils.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/specs/uc2.ads [new file with mode: 0644]

index a263b95e08bf390c1c62039ec958d2257bacd50c..0dbc77918de8549f24c5f69b4dac90b465967244 100644 (file)
@@ -1,3 +1,8 @@
+2017-09-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/utils.c (unchecked_convert): When the result type is a
+       non-biased integral type with size 0, set the result to 0 directly.
+
 2017-09-05  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/gigi.h (renaming_from_generic_instantiation_p): Turn to
index b0f6d2dba1e8ecc9cd04406dfc6f21b1848594eb..1c83a08d5bdd63885500a9f0c908aff5a8e6260c 100644 (file)
@@ -5257,20 +5257,26 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
                                        ? TYPE_RM_SIZE (etype)
                                        : TYPE_SIZE (etype)) == 0)))
     {
-      tree base_type
-       = gnat_type_for_size (TREE_INT_CST_LOW (TYPE_SIZE (type)),
-                             type_unsigned_for_rm (type));
-      tree shift_expr
-       = convert (base_type,
-                  size_binop (MINUS_EXPR,
-                              TYPE_SIZE (type), TYPE_RM_SIZE (type)));
-      expr
-       = convert (type,
-                  build_binary_op (RSHIFT_EXPR, base_type,
-                                   build_binary_op (LSHIFT_EXPR, base_type,
-                                                    convert (base_type, expr),
-                                                    shift_expr),
-                                   shift_expr));
+      if (integer_zerop (TYPE_RM_SIZE (type)))
+       expr = build_int_cst (type, 0);
+      else
+       {
+         tree base_type
+           = gnat_type_for_size (TREE_INT_CST_LOW (TYPE_SIZE (type)),
+                                 type_unsigned_for_rm (type));
+         tree shift_expr
+           = convert (base_type,
+                      size_binop (MINUS_EXPR,
+                                  TYPE_SIZE (type), TYPE_RM_SIZE (type)));
+         expr
+           = convert (type,
+                      build_binary_op (RSHIFT_EXPR, base_type,
+                                       build_binary_op (LSHIFT_EXPR, base_type,
+                                                        convert (base_type,
+                                                                 expr),
+                                                        shift_expr),
+                                       shift_expr));
+       }
     }
 
   /* An unchecked conversion should never raise Constraint_Error.  The code
index f6210be478bd150c2a72757e74141f9ac39b4841..68c4076278d1f566ca238b77336c21710e193ff6 100644 (file)
@@ -1,3 +1,7 @@
+2017-09-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/specs/uc2.ads: New test.
+
 2017-09-05  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/taft_type4.adb: New test.
diff --git a/gcc/testsuite/gnat.dg/specs/uc2.ads b/gcc/testsuite/gnat.dg/specs/uc2.ads
new file mode 100644 (file)
index 0000000..84d4e04
--- /dev/null
@@ -0,0 +1,18 @@
+-- { dg-do compile }
+-- { dg-options "-O" }
+
+with Ada.Unchecked_Conversion;
+
+package UC2 is
+
+  subtype Word_Type is Integer range 0 .. 0;
+  type Arr is array (1 .. Word_Type'Size) of Boolean;
+  pragma Pack(Arr);
+
+  function Conv is
+     new Ada.Unchecked_Conversion (Source => Arr, Target => Word_Type);
+
+  A : Arr;
+  W : Word_Type := Conv(A);
+
+end UC2;