different signedness for bitfield 'char' and plain 'char'

Hi,

I have altered isSignedCharDefault() to make ‘char’ unsigned for the xcore target too.
(The signedness of ‘char’ is an ABI issue as far a the standard is concerned.)

My problem now is that char-bitfields are also being made unsigned.
According to the standard the members of a bitfield are always signed unless explicitly marked unsigned.

Hence I need:
‘char’ to be unsigned.
but the bit field ‘char’ to be signed.

viz:
// ABI requires plain ‘char’ to be unsigned
char c = (char)-1;
assert(c >= 0);

// members of a bitfield are always signed unless explicitly marked unsigned
struct char_sign { char x : 1; };
char_sign.x = 1;
assert(char_sign.x < 0);

Is this possible in clang?
If not, could anyone like to point me in the right direction to where the fix would be necessary?

Thank you

Robert

That's sort of strange... but probably not too hard.

CGBitFieldInfo::MakeInfo in CGRecordLayoutBuilder.cpp is the obvious
place. I'm trying to think of anywhere else that would actually need
to be modified... I mean, it theoretically affects integer promotion,
but in practice sizeof(int) > sizeof(char) so that doesn't actually
matter.

-Eli

Hi,

I have altered isSignedCharDefault() to make ‘char’ unsigned for the xcore target too.
(The signedness of ‘char’ is an ABI issue as far a the standard is concerned.)

My problem now is that char-bitfields are also being made unsigned.
According to the standard the members of a bitfield are always signed unless explicitly marked unsigned.

What standard? C++ requires that bit-fields have the same signedness as their underlying type. If ‘char’ is unsigned, then bit-fields of type ‘char’ are also unsigned.

Hi Richard,

What standard? C++ requires that bit-fields have the same signedness as their underlying type. If ‘char’ is unsigned, then bit-fields of type ‘char’ are also unsigned.
Sorry, I was thinking of the C99 standard.
But I actually was half quoting c++ 2011 standard.
Either way, I was wrong - but still not clear.

The XCore ABI (currently implemented by the XCore llvm-gcc frontend) expects:
‘char’ to be unsigned.
but the bit field ‘char’ to be signed.

Does this infringe the C99 & C++11 standards?
I’ll keep reading but I’m no lawyer.

robert

C++
9.6:p3
It is implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int or long bit-field is signed or unsigned.

C99
6.2.5:p15
The three types char, signed char, and unsigned char are collectively called the character types. The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char.
6.7.2:p5
Each of the comma-separated sets designates the same type, except that for bit-fields, it is implementation-defined whether the specifier int designates the same type as signed int or the same type as unsigned int.
6.7.2.1:p9
A bit-field is interpreted as a signed or unsigned integer type consisting of the specified number of bits. 105
105) As specified in 6.7.2 above, if the actual type specifier used is int or a typedef-name defined as int, then it is implementation-defined whether the bit-field is signed or unsigned.

Hi Richard,

What standard? C++ requires that bit-fields have the same signedness as their underlying type. If ‘char’ is unsigned, then bit-fields of type ‘char’ are also unsigned.

Sorry, I was thinking of the C99 standard.
But I actually was half quoting c++ 2011 standard.
Either way, I was wrong - but still not clear.

The XCore ABI (currently implemented by the XCore llvm-gcc frontend) expects:

‘char’ to be unsigned.
but the bit field ‘char’ to be signed.

Does this infringe the C99 & C++11 standards?

This is fine in C99, but not permitted by C++11 (and arguably, because the relevant DR applied to all versions of C++, is also not permitted in any earlier version of C++ either).

Note that the x86_64 ABI also claims that plain (neither signed nor unsigned) bit-fields are unsigned, but it is simply wrong. Maybe the XCore ABI document is wrong too?

Hi Richard,

I only have access to a working draft of the C++11 standard (N3242=11-0012, date 2011-02-28)
All I can find is as quoted before:
9.6:p3
It is implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int or long bit-field is signed or unsigned.

I’ve tried finding any further statement but have not been successful.
Please could you direct me to the relevant clause.

robert

Hi Richard,

I only have access to a working draft of the C++11 standard (N3242=11-0012, date 2011-02-28)
All I can find is as quoted before:

9.6:p3
It is implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int or long bit-field is signed or unsigned.

This text was removed by DR739:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#739

This text was removed by DR739:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#739

To be fair, that looks like a C++1y change (made Feb 2012).

Tim.

Thank you!
Now to change the XCore ABI instead…
Educated and appreciative.
Robert

Agreed, but it was a DR against C++11 (and earlier).

It’s also potentially unimplementable to the extent that ABIs may have codified different rules.

John.