Unwanted warning on assigning negatives to unsigned bit-fields

Hi everybody,

I'm suffering from an annoying warning. Here's an example to quickly reproduce it:

    #include <stdio.h>
    #include <stdint.h>
    #include <inttypes.h>

    typedef union _bf
    {
        struct
        {
            uint32_t field1:2;
            uint32_t field2:30;
        } fields;
        uint32_t raw;
    } bf;

    int main(int argc, char *argv)
    {
        printf("0x%" PRIx32 "\n"
               "0x%" PRIx32 "\n",
                ((bf){ .fields.field1 = -1 }).raw, //Warning
                ((bf){ .raw = -1 }).raw ); //No warning
        return 0;
    }

Compilation: clang -std=c99 -m32 -O2 -o test test.c

Result: test.c:19:37: warning: implicit truncation from 'int' to bit-field changes value from -1 to 3

Could someone, please, explain me, why the warning is produced? The C99 standard is very clear about the behaviour
with respect to the value of field1 (the value of raw after assigning to field1 is implementation-defined, but that's
a different story), and it is unambiguous:

6.3.1.3 paragraph 2
"if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum
value that can be represented in the new type until the value is in the range of the new type"

6.7.2.1 paragraph 9:
"A bit-field is interpreted as a signed or unsigned integer type consisting of the specified number of bits"

So field1 is an unsigned integer consisting of 2 bits. The maximum value that it can store is 2^2-1 . In order to
assign -1 to field1 2^2-1+1 must be added to -1. The result is therefore well-defined to be 3. So as long as assigning
-1 to any standard unsigned integer does not produce any warning, I see no reason behind producing it for unsigned
bit-fields. Especially because this is the most convenient way to set all bits in a bit-field. A single-bit bit-field
would be a somewhat special case for assigning -1, but I'd prefer to not have the warning in this case as well.

Kind regards

Richard - perhaps you could take a look at this diagnostic quality issues/possible inconsistency?

I think what’s happening is -1 has type int, then gets converted to unsigned, then assigned to the bit field. As an unsigned value, the minimum number of bits required is the full bit width, resulting in the warning. I am look further into this.

Thanks for taking a look. I just want to note that this behaviour wouldn't be compatible with the C99. And if true
it's also not consistent across different widths:

    typedef union _bf {
        struct {
            uint16_t field1:16; //Warning. Assigned 0xffff
        } fields;
        uint16_t raw;
    } bf;

    typedef union _bf {
        struct {
            uint32_t field1:32; //No warning. Assigned 0xffffffff
        } fields;
        uint32_t raw;
    } bf;

    typedef union _bf {
        struct {
            uint64_t field1:64; //No warning. Assigned 0xffffffffffffffff
        } fields;
        uint64_t raw;
    } bf;

So assuming it's first converted to the unsigned int before assignment it would then assign 0xffffffff in the third
case (which would also contradict the standard). On the other hand if -1 is first converted to the (full-width) type
of the bit-field, then it would not generate a warning in the first case.

In any case the correct behaviour is to convert directly into the integer type consisting of the specified number of
bits. And to be consistent with the assignment of negatives to standard unsigned integers the warning should only be
generated for negatives that do not fit into the signed counterpart of the bit-field type consisting of the specified
number of bits.

Are there any new discoveries on the issue?