struct { unsigned int x:1; } foo; int bar = 0; foo.x = bar != 0; // warning foo.x = bar != 0 ? 1 : 0; // warning if (bar != 0) foo.x = 1; else foo.x = 0; // no warnings, but too ugly..
Confirmed. Notes: foo.x = bar != 0; // only warns in C, not in C++. foo.x = bar != 0 ? 1 : 0; // warning is not a problem of bitfields but for every conditional expression, the following also warns short x = (bar != 0) ? 1 : 0; // conversion to ‘short int’ from ‘int’ may alter its value To fix the two last warnings, we need to look into the arguments of the conditional expression.
In C++ we have: <ne_expr 0x2aaaab627f00 type <boolean_type 0x2aaaab4fb9c0 bool public unsigned QI size <integer_cst 0x2aaaab4e87b0 constant invariant 8> unit size <integer_cst 0x2aaaab4e87e0 constant invariant 1> align 8 symtab 0 alias set -1 canonical type 0x2aaaab4fb9c0 precision 1 min <integer_cst 0x2aaaab4e8cc0 0> max <integer_cst 0x2aaaab4e8d20 1>> In C we have: <ne_expr 0x2aaaab4c4240 type <integer_type 0x2aaaab4f8540 int public SI size <integer_cst 0x2aaaab4e8a80 constant invariant 32> unit size <integer_cst 0x2aaaab4e86f0 constant invariant 4> align 32 symtab 0 alias set -1 canonical type 0x2aaaab4f8540 precision 32 min <integer_cst 0x2aaaab4e89f0 -2147483648> max <integer_cst 0x2aaaab4e8a20 214748364\ 7> pointer_to_this <pointer_type 0x2aaaab507b40>> Is there are reason for not using boolean_type internally for boolean expressions even in C? A quick hack would be to check the expression and if it boolean, just consider that the expression type is boolean_type. I have seen other bug elsewhere where not using boolean_type causes trouble...
Subject: Bug 35635 Author: manu Date: Wed Aug 13 10:01:52 2008 New Revision: 139049 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=139049 Log: 2008-08-13 Manuel Lopez-Ibanez <manu@gcc.gnu.org> PR 35635 * c-common.c (conversion_warning): Use a switch. Ignore boolean expressions except for conversions to signed:1 bitfields. Handle COND_EXPR with constant operands. testsuite/ * gcc.dg/pr35635.c: New. * gcc.dg/Wconversion-integer.c: Update. * gcc.dg/Wconversion-integer-no-sign.c: Update. * gcc.dg/Wsign-conversion.c: Update. * g++.dg/warn/pr35635.C: New. * g++.dg/warn/Wconversion-integer.C: Update. * g++.dg/warn/Wsign-conversion.C: Update. Added: trunk/gcc/testsuite/g++.dg/warn/pr35635.C trunk/gcc/testsuite/gcc.dg/pr35635.c Modified: trunk/gcc/ChangeLog trunk/gcc/c-common.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/g++.dg/warn/Wconversion-integer.C trunk/gcc/testsuite/g++.dg/warn/Wsign-conversion.C trunk/gcc/testsuite/gcc.dg/Wconversion-integer-no-sign.c trunk/gcc/testsuite/gcc.dg/Wconversion-integer.c trunk/gcc/testsuite/gcc.dg/Wsign-conversion.c
FIXED in GCC 4.4