Skip to content

[Clang][C] What is the type of a bit-field? (For generic selection / constexpr initialization) #101299

Open
@MitalAshok

Description

@MitalAshok

Seen at #78112 (review), this compiles surprisingly in C23:

struct C {
  signed long long i : 8;
};
constexpr struct C c = { 255 };

My reading of N3096:

§6.7.1p6:

If an object or subobject declared with storage-class specifier constexpr has [...] integer [..] type, any explicit initializer value for it shall be [.,.] an integer constant expression

§6.6p4:

Each constant expression shall evaluate to a constant that is in the range of representable values for its type.

§6.7.2.1p12:

A bit-field is interpreted as having a signed or unsigned integer type consisting of the specified number of bits.

... So the member i has a signed type with 8 bits, which 255 is not representable in, and Clang should reject the initializer.

Two other places I can think of where the type of something is observed is typeof (which explicitly bans bit-fields), and _Generic. Clang currently allows:

struct C {
  signed long long i : 8;
} c;
static_assert(_Generic(c.i, long long: 1));

which according to §6.7.2.1p12, it shouldn't? The bit-field type with width 8 should not be compatible with a 64 bit wide type. Unless the lvalue conversion done converts the bit-field type to long long, but that doesn't seem to be allowed by §6.3.2.1

CC @AaronBallman @Fznamznon

See also:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88731
DR#315
DR#481

Metadata

Metadata

Assignees

Labels

accepts-invalidc23clang:frontendLanguage frontend issues, e.g. anything involving "Sema"confirmedVerified by a second party

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions