]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/45034 ("safe" conversion from unsigned to signed char gives...
authorRichard Guenther <rguenther@suse.de>
Thu, 29 Jul 2010 10:59:54 +0000 (10:59 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 29 Jul 2010 10:59:54 +0000 (10:59 +0000)
2010-07-29  Richard Guenther  <rguenther@suse.de>

PR middle-end/45034
* convert.c (convert_to_integer): Always use an unsigned
type for narrowed negate and bitwise not.

* gcc.c-torture/execute/pr45034.c: New testcase.

From-SVN: r162673

gcc/ChangeLog
gcc/convert.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr45034.c [new file with mode: 0644]

index ffbe8b214a5562c348d91654248c6cb9f0fc007c..5c066b524b4c4e7979f895f7b958fb93230b4ed0 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-29  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/45034
+       * convert.c (convert_to_integer): Always use an unsigned
+       type for narrowed negate and bitwise not.
+
 2010-07-29  Ira Rosen  <irar@il.ibm.com>
 
        * tree-vect-loop.c (vect_create_epilog_for_reduction): Switch
index 48f3f944c714d09672c8ef7f49ccd9d6769d304f..57eedbf538826968675cfd5954f9fac9dab3a3f2 100644 (file)
@@ -799,14 +799,7 @@ convert_to_integer (tree type, tree expr)
          /* This is not correct for ABS_EXPR,
             since we must test the sign before truncation.  */
          {
-           tree typex;
-
-           /* Don't do unsigned arithmetic where signed was wanted,
-              or vice versa.  */
-           if (TYPE_UNSIGNED (TREE_TYPE (expr)))
-             typex = unsigned_type_for (type);
-           else
-             typex = signed_type_for (type);
+           tree typex = unsigned_type_for (type);
            return convert (type,
                            fold_build1 (ex_form, typex,
                                         convert (typex,
index 3ccd402b8ceabd70e8b6fc5b1346782008ffd5e1..a41b82026317e1a91fc38e6363832e515596fb30 100644 (file)
@@ -1,3 +1,8 @@
+2010-07-29  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/45034
+       * gcc.c-torture/execute/pr45034.c: New testcase.
+
 2010-07-28  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/45096
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr45034.c b/gcc/testsuite/gcc.c-torture/execute/pr45034.c
new file mode 100644 (file)
index 0000000..2d86f30
--- /dev/null
@@ -0,0 +1,45 @@
+extern void abort (void);
+static void fixnum_neg(signed char x, signed char *py, int *pv)
+{
+  unsigned char ux, uy;
+
+  ux = (unsigned char)x;
+  uy = -ux;
+  *py = (uy <= 127) ? (signed char)uy : (-(signed char)(255 - uy) - 1);
+  *pv = (x == -128) ? 1 : 0;
+}
+
+void __attribute__((noinline)) foo(int x, int y, int v)
+{
+  if (y < -128 || y > 127)
+    abort();
+}
+
+int test_neg(void)
+{
+  signed char x, y;
+  int v, err;
+
+  err = 0;
+  x = -128;
+  for (;;) {
+      fixnum_neg(x, &y, &v);
+      foo((int)x, (int)y, v);
+      if ((v && x != -128) || (!v && x == -128))
+       ++err;
+      if (x == 127)
+       break;
+      ++x;
+  }
+  return err;
+}
+
+int main(void)
+{
+  if (sizeof (char) != 1)
+    return 0;
+  if (test_neg() != 0)
+    abort();
+  return 0;
+}
+