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]

[PATCH] Fix PR optimization/11210


Hi,

This is another specimen in the famous series of weird bugs in the constant 
expressions folder. It has been present since at least GCC 2.95.3. The 
compiler reports the truth expression

	struct str { 
	  int head; 
	  char data[8];
	} t;

	t.data[0] || (unsigned char) t.data[2] != 130;

as being 'always 1', because it doesn't take into account the cast.

decode_field_reference() throws away surrounding NOPs in the expression it is 
passed. Now it sets 'punsignedp' to the signedness of the field, so I think 
it must strip only NOPs that don't affect the sign.

Bootstrapped/regtested (mainline, except Ada) on i586-redhat-linux-gnu.

-- 
Eric Botcazou


2003-06-18  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR optimization/11210
	* fold-const (decode_field_reference): Strip only NOPs
	that don't affect the sign.


2003-06-18  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* gcc.dg/20030618-1.c: New test.
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.265
diff -u -p -r1.265 fold-const.c
--- fold-const.c	16 Jun 2003 21:41:03 -0000	1.265
+++ fold-const.c	18 Jun 2003 15:09:18 -0000
@@ -2742,7 +2742,8 @@ decode_field_reference (exp, pbitsize, p
   if (! INTEGRAL_TYPE_P (TREE_TYPE (exp)))
     return 0;
 
-  STRIP_NOPS (exp);
+  /* Signedness matters here.  */
+  STRIP_SIGN_NOPS (exp);
 
   if (TREE_CODE (exp) == BIT_AND_EXPR)
     {
/* PR optimization/11210 */
/* Originator: Guido Classen <guido@clagi.de> */
/* Reduced testcase by Falk Hueffner <falk@debian.org> */
/* { dg-do compile } */
/* { dg-options "-O" } */

/* Verify that the constant expressions folder doesn't
   throw away the cast operation in the comparison.  */

struct str { 
  int head; 
  char data[8];
};

int foo(struct str t)
{
  return t.data[0] || (unsigned char) t.data[2] != 130; /* { dg-bogus "comparison is always 1" } */
}

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