This is an archive of the discontinued LLVM Phabricator instance.

Further update -Wbitfield-constant-conversion for 1-bit bitfield
ClosedPublic

Authored by aaron.ballman on Aug 29 2022, 7:11 AM.

Details

Summary

https://reviews.llvm.org/D131255 (82afc9b169a67e8b8a1862fb9c41a2cd974d6691) began warning about conversion causing data loss for a single-bit bit-field. However, after landing the changes, there were reports about significant false positives from some code bases.

This alters the approach taken in that patch by introducing a new warning group (-Wsingle-bit-bitfield-constant-conversion) which is grouped under -Wbitfield-constant-conversion to allow users to selectively disable the single-bit warning without losing the other constant conversion warnings.

Diff Detail

Event Timeline

aaron.ballman created this revision.Aug 29 2022, 7:11 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 29 2022, 7:11 AM
aaron.ballman requested review of this revision.Aug 29 2022, 7:11 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 29 2022, 7:11 AM

LGTM, questioning whether we want to do some macro introspection in C mode (as the CORRECT way to use these 1 bit-bitfields is as a bool), but at least this gives the person the ability to disable this warning.

clang/test/Sema/constant-conversion.c
24–25

Can you add a test that shows this isn't diagnosed:

s.b = true;?

Thanks to stdbool.h, this of course might have to be in the C++ test (or C23). Makes me question whether we need to do some detection to see if someone has written the above.

Added a test case for true in C++, and added similar logic for C to reduce the chance for false positives. If the user uses true (the macro from stdbool.h), they're signaling an intent that the field is used in boolean contexts. The macro expands to 1 (per spec) but should not be diagnosed because the actual value stored only needs to be nonzero to have the correct boolean semantics.

erichkeane accepted this revision.Aug 29 2022, 8:34 AM

2 nits, otherwise LGTM.

clang/lib/Sema/SemaChecking.cpp
13080

Might consider hoisting this line above the macro-checking, and just use it in both cases. Also, perhaps a more descriptive name? IsInvalidSignedOneBitAssignment ?

This revision is now accepted and ready to land.Aug 29 2022, 8:34 AM

Update based on review feedback.

erichkeane accepted this revision.Aug 29 2022, 9:13 AM

Still LGTM.

bjope added a subscriber: bjope.Sep 1 2022, 4:58 AM
bjope added inline comments.
clang/test/Sema/constant-conversion.c
30

(Sorry for being late to the party, with post commit comments. I'm just trying to understand the reasoning about always suppressing the warning based on "true".)

Isn't the code a bit suspicious when using true/false from stdbool.h, while using a signed bitfield?

When doing things like

(s.b == true) ? 1 : 0

the result would always be zero if s.b is a signed 1-bit bitfield.

So wouldn't it make more sense to actually use an unsigned bitfield (such as the bool type from stdbool.h) when the intent is to store a boolean value and using defines from stdbool.h?

Is perhaps the idea that we will get warnings about (s.b == true) being redundant in situations like this, and then we do not need a warning on the bitfield assignment? Such a reasoning would actually make some sense, since (s.b == true) never would be true even when the bitfield is assigned a non-constant value, so we can't rely on catching the problem by only looking at bitfield assignments involving true/false.

aaron.ballman added inline comments.Sep 1 2022, 10:28 AM
clang/test/Sema/constant-conversion.c
30

Isn't the code a bit suspicious when using true/false from stdbool.h, while using a signed bitfield?

Yes and no...

When doing things like

(s.b == true) ? 1 : 0

the result would always be zero if s.b is a signed 1-bit bitfield.

You're correct, but that's a bit of a code smell because of == true.

So wouldn't it make more sense to actually use an unsigned bitfield (such as the bool type from stdbool.h) when the intent is to store a boolean value and using defines from stdbool.h?

Yes, ideally.

Is perhaps the idea that we will get warnings about (s.b == true) being redundant in situations like this, and then we do not need a warning on the bitfield assignment? Such a reasoning would actually make some sense, since (s.b == true) never would be true even when the bitfield is assigned a non-constant value, so we can't rely on catching the problem by only looking at bitfield assignments involving true/false.

The idea is more that someone using true is more likely to be treating the field as a boolean and so they won't be comparing the bit-field against a specific value, but instead testing it for its boolean value. This also unifies the behavior between C and C++: https://godbolt.org/z/WKP4xcPzT

We don't currently issue a diagnostic on == true, but that sure seems like something -Wtautological-compare should pick up on (for bit-fields in general, not just for one-bit bit-fields): https://godbolt.org/z/Tj4711Ysc

(Note, godbolt seems to have a Clang trunk that's ~8 days old, so diagnostic behavior doesn't match actual trunk yet. That caught me by surprise.)

bjope added inline comments.Sep 2 2022, 4:12 AM
clang/test/Sema/constant-conversion.c
30

Ok, thanks! Sounds reasonable to me.

aaron.ballman added inline comments.Sep 2 2022, 5:44 AM
clang/test/Sema/constant-conversion.c
30

Great! Thank you for the discussion! (FWIW, it's *totally* fine to give post commit feedback, so no need to apologize. You're never late to the "why does this work that way?" party.)