expr.c (expand_expr_real_2): Properly truncate the BIT_NOT_EXPR expansion result...
authorRichard Guenther <rguenther@suse.de>
Mon, 18 Jul 2011 13:39:28 +0000 (13:39 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 18 Jul 2011 13:39:28 +0000 (13:39 +0000)
2011-07-18  Richard Guenther  <rguenther@suse.de>

* expr.c (expand_expr_real_2): Properly truncate the BIT_NOT_EXPR
expansion result to bitfield precision if required.

* gcc.dg/torture/20110718-1.c: New testcase.

From-SVN: r176398

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/20110718-1.c [new file with mode: 0644]

index 6026f4a..5907bf2 100644 (file)
@@ -1,3 +1,8 @@
+2011-07-18  Richard Guenther  <rguenther@suse.de>
+
+       * expr.c (expand_expr_real_2): Properly truncate the BIT_NOT_EXPR
+       expansion result to bitfield precision if required.
+
 2011-07-18  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * config.gcc (i[3456x]86-*-netware*): Remove.
index ee11142..0f20372 100644 (file)
@@ -8037,7 +8037,15 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
                         VOIDmode, EXPAND_NORMAL);
       if (modifier == EXPAND_STACK_PARM)
        target = 0;
-      temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
+      /* In case we have to reduce the result to bitfield precision
+        expand this as XOR with a proper constant instead.  */
+      if (reduce_bit_field)
+       temp = expand_binop (mode, xor_optab, op0,
+                            immed_double_int_const
+                              (double_int_mask (TYPE_PRECISION (type)), mode),
+                            target, 1, OPTAB_LIB_WIDEN);
+      else
+       temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
       gcc_assert (temp);
       return temp;
 
index 65125bd..32f59bd 100644 (file)
@@ -1,3 +1,7 @@
+2011-07-18  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.dg/torture/20110718-1.c: New testcase.
+
 2011-07-18  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * g++.dg/ext/bitfield2.C: Remove i?86-*-netware support.
diff --git a/gcc/testsuite/gcc.dg/torture/20110718-1.c b/gcc/testsuite/gcc.dg/torture/20110718-1.c
new file mode 100644 (file)
index 0000000..ccabbd9
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+
+extern void abort (void);
+struct X {
+#if (__SIZEOF_LONG__ != __SIZEOF_INT__) && (__SIZEOF_LONG__ == 8)
+  unsigned long i : 33;
+#else
+  unsigned long i;
+#endif
+};
+unsigned long __attribute__((noinline))
+foo (struct X *p)
+{
+  return ~p->i;
+}
+int main()
+{
+  struct X x;
+  x.i = -1;
+  if (foo (&x) != 0)
+    abort ();
+  return 0;
+}