Re: Bug in bitfield handling?
On Sep 7, 2012, at 2:02 PM, Andrew Pinski wrote: > On Fri, Sep 7, 2012 at 10:57 AM, wrote: >> This seems to be a bug: >> >> struct bug >> { >>int f1:1; >>unsigned long long f2:31; >> }; >> >> struct bug test = { 1, 0x8000ULL }; >> >> int main (int c, char **v) >> { >>unsigned long long tf2; >> >>tf2 = test.f2 << 16; >>if (tf2 == 0x8000ULL) >>return 0; >>return 1; >> } >> >> Since the underlying type of field f2 is unsigned long long, I would not >> expect the expression "test.f2 << 16" to do sign extending of a 32 bit >> intermediate result. But that is in fact what GCC produces, for >> x86_64-linux (gcc 4.7.0). >> >> If I explicitly cast test.f2 to unsigned long long before the shift, the >> expected result appears. But I shouldn't have to do that cast, given that >> the type of f2 is already unsigned long long, correct? > > The type of "test.f2" is a 31 bit unsigned integer (the declared type > is used for alignment) and that fits in a 32bit signed integer so when > doing test.f2 << 16, it is promoted to only an 32bit signed integer. > > Thanks, > Andrew Ok, thanks. GDB doesn't do things this way, so I guess I have to tell them. paul
Re: Bug in bitfield handling?
On Fri, Sep 7, 2012 at 10:57 AM, wrote: > This seems to be a bug: > > struct bug > { > int f1:1; > unsigned long long f2:31; > }; > > struct bug test = { 1, 0x8000ULL }; > > int main (int c, char **v) > { > unsigned long long tf2; > > tf2 = test.f2 << 16; > if (tf2 == 0x8000ULL) > return 0; > return 1; > } > > Since the underlying type of field f2 is unsigned long long, I would not > expect the expression "test.f2 << 16" to do sign extending of a 32 bit > intermediate result. But that is in fact what GCC produces, for x86_64-linux > (gcc 4.7.0). > > If I explicitly cast test.f2 to unsigned long long before the shift, the > expected result appears. But I shouldn't have to do that cast, given that > the type of f2 is already unsigned long long, correct? The type of "test.f2" is a 31 bit unsigned integer (the declared type is used for alignment) and that fits in a 32bit signed integer so when doing test.f2 << 16, it is promoted to only an 32bit signed integer. Thanks, Andrew > > paul >
Bug in bitfield handling?
This seems to be a bug: struct bug { int f1:1; unsigned long long f2:31; }; struct bug test = { 1, 0x8000ULL }; int main (int c, char **v) { unsigned long long tf2; tf2 = test.f2 << 16; if (tf2 == 0x8000ULL) return 0; return 1; } Since the underlying type of field f2 is unsigned long long, I would not expect the expression "test.f2 << 16" to do sign extending of a 32 bit intermediate result. But that is in fact what GCC produces, for x86_64-linux (gcc 4.7.0). If I explicitly cast test.f2 to unsigned long long before the shift, the expected result appears. But I shouldn't have to do that cast, given that the type of f2 is already unsigned long long, correct? paul