This is an archive of the discontinued LLVM Phabricator instance.

C11 _Bool bitfield diagnostic
ClosedPublic

Authored by rcraik on May 25 2015, 2:06 PM.

Details

Summary

Implement DR262 (for C). This patch will mainly affect bitfields of type _Bool

Diff Detail

Event Timeline

rcraik updated this revision to Diff 26425.May 25 2015, 2:06 PM
rcraik retitled this revision from to C11 _Bool bitfield diagnostic.
rcraik updated this object.
rcraik edited the test plan for this revision. (Show Details)
rcraik added reviewers: rsmith, fraggamuffin.
rcraik added subscribers: Unknown Object (MLST), hubert.reinterpretcast.

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.

rsmith added inline comments.Jun 1 2015, 9:05 PM
include/clang/Basic/DiagnosticSemaKinds.td
4324–4329

Since this is a constraint violation according to the C11 standard, this should be an ExtWarn or Extension rather than merely a Warning.

4324–4329

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
12653

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
4324–4329

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
12653

Yes, this was a change applied in TC2.

rcraik updated this revision to Diff 27552.Jun 11 2015, 3:00 PM

I've updated the patch to produce the warning in C99 as well as C11 modes

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.

rcraik marked 2 inline comments as done.Aug 6 2015, 3:03 PM
rcraik updated this revision to Diff 34339.Sep 9 2015, 8:04 AM

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?

rsmith added inline comments.Sep 9 2015, 11:59 AM
include/clang/Basic/DiagnosticSemaKinds.td
4324–4329

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
12627–12628

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).

12653

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.

12655

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
12655

I think this is PR 23505.

lib/Sema/SemaDecl.cpp
12627–12628

The implementation of getIntWidth currently makes this consideration moot at this time, but should this extend to C89 (aside from the _Bool extension)?

rcraik added inline comments.Sep 10 2015, 2:17 PM
lib/Sema/SemaDecl.cpp
12627–12628

I think we have three options (the special case for _Bool bitfields being removed in each case):

  1. change getTypeSize to getIntWidth and leave the rest of the checks as-is
  2. change getTypeSize to getIntWidth and update the C/MS diagnostic to either ExtWarn or Warning (for some or all language levels)
  3. leave as getTypeSize for lower language levels

Opinions?

rcraik updated this revision to Diff 34571.Sep 11 2015, 1:05 PM
rcraik updated this object.

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.

rcraik marked 3 inline comments as done.Sep 11 2015, 1:07 PM
rsmith accepted this revision.Sep 11 2015, 1:14 PM
rsmith edited edge metadata.

Looks great, please go ahead. Sorry it's taken so long to get this reviewed.

This revision is now accepted and ready to land.Sep 11 2015, 1:14 PM
rcraik closed this revision.Sep 14 2015, 2:28 PM