Re: Bug in bitfield handling?

2012-09-07 Thread Paul_Koning

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?

2012-09-07 Thread Andrew Pinski
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?

2012-09-07 Thread Paul_Koning
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