Implement DR262 (for C). This patch will mainly affect bitfields of type _Bool
Details
Diff Detail
Event Timeline
The change in the C11 Standard is that the number of bits in the value representation is now used as opposed to the number of bits in the object representation. The message is generic to allow for additional types with padding bits; however, the change does not use a generic mechanism to handle such types.
In addition, feedback is requested as to whether the message for the case of _Bool should be limited to C11 modes or not.
include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
4320–4325 | Since this is a constraint violation according to the C11 standard, this should be an ExtWarn or Extension rather than merely a Warning. | |
4320–4325 | I think this diagnostic should be more specific. The diagnostic text should make it clear that: (1) the problem is that the field has a boolean type, and (2) why that might deserve a warning. Something like "ISO C11 forbids bit-field of type %0 of size greater than 1 (%1 specified)", maybe. | |
lib/Sema/SemaDecl.cpp | ||
12611 | It looks like this should apply in all modes that aren't C++: even in C99, we have a constraint in 6.7.2.1 that the specified bit-width cannot be greater than the width of the type, and width is defined in 6.2.6.2 as the number of precision + sign bits. |
include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
4320–4325 | I have not found any normative text which indicates that _Bool cannot have width greater then 1. Also, the proposed new message text makes it less clear that the property is platform-dependent. Note that the check associated with _Bool hard-codes "1", and the message may be emitted even when the constraint is not violated. The message text proposed in the patch is sufficiently generic to accommodate that. | |
lib/Sema/SemaDecl.cpp | ||
12611 | Yes, this was a change applied in TC2. |
The values of _Bool is not limited to 0 and 1 in C (although storing such a value is not straightforward). It is conceivable that some platforms would have _Bool, aside from conversions, behave the same as unsigned char. My earlier statement that the message is sufficiently generic does not take this consideration into account.
It seems making this a plain warning specifically for _Bool on a portability basis is viable; however, the best argument I could come up with for why _Bool warrants special treatment is that it is somewhat likely to have padding bits. My guess is that implementations which consider _Bool to have padding bits are likely to consider all cases where the padding bits are non-zero to be trap representations.
I've updated the message to make it a bit clearer that this is a portability concern. Are there any further concerns with this patch?
include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
4320–4325 | I suppose your argument for the width of _Bool being possibly greater than 1 is that, while _Bool is required to be large enough to store the values 0 and 1 (6.2.5/2), it may theoretically have value bits representing 2, 4, 8, ... (even though 6.3.1.2/1 does not allow creation of a value that sets those bits). That interpretation seems consistent with C's rules. However, for Clang, the width of _Bool is 1, so this is a constraint violation. | |
lib/Sema/SemaDecl.cpp | ||
12586 | I think the right way to fix this is to call getIntWidth here instead of getTypeSize, and finesse our error message to clarify that we're talking about the width of the type (the number of value bits) rather than the size of the type (the number of storage bits). | |
12611 | This is redundant: C99 is always set whenever C11 is (C99 means "C99 or later"). Just test for C99 here. I also think we should apply this rule to C89, where we support _Bool as an extension and use the C99 rules for it. The above check for !CPlusPlus seems right. | |
12613 | This will assert if the specified bitfield width doesn't fit in 64 bits. You can use Value.ugt(1) instead. The check above for TypeSize has the same bug. This testcase causes an assertion to fire: struct X { int n : 0xffffffff * (__int128)0xffffffff * 0xffffffff; }; |
lib/Sema/SemaDecl.cpp | ||
---|---|---|
12613 | I think this is PR 23505. |
lib/Sema/SemaDecl.cpp | ||
---|---|---|
12586 | The implementation of getIntWidth currently makes this consideration moot at this time, but should this extend to C89 (aside from the _Bool extension)? |
lib/Sema/SemaDecl.cpp | ||
---|---|---|
12586 | I think we have three options (the special case for _Bool bitfields being removed in each case):
Opinions? |
switched to using getIntWidth instead of getTypeSize and updated the error and warning messages accordingly, as have the necessary test cases. The separate check for _Bool bitfields has been removed, so the check is now consistent for all types.
Since this is a constraint violation according to the C11 standard, this should be an ExtWarn or Extension rather than merely a Warning.