This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix shorten_compare (PR c/48197)


On Mon, Mar 21, 2011 at 04:31:31PM +0000, Joseph S. Myers wrote:
> On Sun, 20 Mar 2011, Jakub Jelinek wrote:
> 
> > 2011-03-20  Jakub Jelinek  <jakub@redhat.com>
> > 
> > 	PR c/48197
> > 	* c-common.c (shorten_compare): If primopN is first sign-extended
> > 	to opN and then zero-extended to result type, set primopN to opN.
> > 
> > 	* gcc.c-torture/execute/pr48197.c: New test.
> 
> This is OK, in that I believe it is (a) correct and (b) a sensible place 
> in the current context to fix this to avoid problems with shorten_compare 
> not working with mixed extensions.  It's worth checking if this fixes PR 
> 42544 as well, since that also looks like it involves mixed extensions.

It does, so here is what I've actually committed:

2011-03-20  Jakub Jelinek  <jakub@redhat.com>

	PR c/42544
	PR c/48197
	* c-common.c (shorten_compare): If primopN is first sign-extended
	to opN and then zero-extended to result type, set primopN to opN.

	* gcc.c-torture/execute/pr42544.c: New test.
	* gcc.c-torture/execute/pr48197.c: New test.

--- gcc/c-family/c-common.c.jj	2011-03-21 13:00:03.000000000 +0100
+++ gcc/c-family/c-common.c	2011-03-21 18:29:23.000000000 +0100
@@ -3301,6 +3301,20 @@ shorten_compare (tree *op0_ptr, tree *op
   primop0 = get_narrower (op0, &unsignedp0);
   primop1 = get_narrower (op1, &unsignedp1);
 
+  /* If primopN is first sign-extended from primopN's precision to opN's
+     precision, then zero-extended from opN's precision to
+     *restype_ptr precision, shortenings might be invalid.  */
+  if (TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (TREE_TYPE (op0))
+      && TYPE_PRECISION (TREE_TYPE (op0)) < TYPE_PRECISION (*restype_ptr)
+      && !unsignedp0
+      && TYPE_UNSIGNED (TREE_TYPE (op0)))
+    primop0 = op0;
+  if (TYPE_PRECISION (TREE_TYPE (primop1)) < TYPE_PRECISION (TREE_TYPE (op1))
+      && TYPE_PRECISION (TREE_TYPE (op1)) < TYPE_PRECISION (*restype_ptr)
+      && !unsignedp1
+      && TYPE_UNSIGNED (TREE_TYPE (op1)))
+    primop1 = op1;
+
   /* Handle the case that OP0 does not *contain* a conversion
      but it *requires* conversion to FINAL_TYPE.  */
 
--- gcc/testsuite/gcc.c-torture/execute/pr42544.c.jj	2011-03-21 18:25:01.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr42544.c	2011-03-21 18:24:29.000000000 +0100
@@ -0,0 +1,14 @@
+/* PR c/42544 */
+
+extern void abort (void);
+
+int
+main ()
+{
+  signed short s = -1;
+  if (sizeof (long long) == sizeof (unsigned int))
+    return 0;
+  if ((unsigned int) s >= 0x100000000ULL)
+    abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.c-torture/execute/pr48197.c.jj	2011-03-21 18:29:23.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr48197.c	2011-03-21 18:29:23.000000000 +0100
@@ -0,0 +1,25 @@
+/* PR c/48197 */
+
+extern void abort (void);
+static int y = 0x8000;
+
+int
+main ()
+{
+  unsigned int x = (short)y;
+  if (sizeof (0LL) == sizeof (0U))
+    return 0;
+  if (0LL > (0U ^ (short)-0x8000))
+    abort ();
+  if (0LL > (0U ^ x))
+    abort ();
+  if (0LL > (0U ^ (short)y))
+    abort ();
+  if ((0U ^ (short)-0x8000) < 0LL)
+    abort ();
+  if ((0U ^ x) < 0LL)
+    abort ();
+  if ((0U ^ (short)y) < 0LL)
+    abort ();
+  return 0;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]