This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR optimization/11210
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 18 Jun 2003 18:05:08 +0200
- Subject: [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" } */
}