From 50c43e228542cc1b211c9b2dd6e50cc1ea7b002a Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sun, 9 Oct 2022 13:58:55 +0000 Subject: [PATCH] C front-end: zero-width bit-fields must not have a declarator The C standard forbids this and compilers rightly reject this. --- regression/ansi-c/bitfields2/main.c | 39 ++++++++++++++++++++++++++ regression/ansi-c/bitfields2/test.desc | 9 ++++++ src/ansi-c/c_typecheck_type.cpp | 10 +++++++ 3 files changed, 58 insertions(+) create mode 100644 regression/ansi-c/bitfields2/main.c create mode 100644 regression/ansi-c/bitfields2/test.desc diff --git a/regression/ansi-c/bitfields2/main.c b/regression/ansi-c/bitfields2/main.c new file mode 100644 index 00000000000..03e71366971 --- /dev/null +++ b/regression/ansi-c/bitfields2/main.c @@ -0,0 +1,39 @@ +#include + +#define CONCAT(a, b) a##b +#define CONCAT2(a, b) CONCAT(a, b) + +#define STATIC_ASSERT(condition) \ + int CONCAT2(some_array, __LINE__)[(condition) ? 1 : -1] + +#if CHAR_BIT == 8 +struct bits +{ + char a : 4; + char b : 4; + char c : 4; + char d : 4; + char : 0; // this is ok: no declarator + int i; +}; + +STATIC_ASSERT(sizeof(struct bits) == 2 * sizeof(int)); + +# pragma pack(1) +struct packed_bits +{ + char a : 4; + char b : 4; + char c : 4; + char d : 4; + char x : 0; // this is not permitted + int i; +}; +# pragma pack() + +STATIC_ASSERT(sizeof(struct packed_bits) == sizeof(int) + 2); +#endif + +int main() +{ +} diff --git a/regression/ansi-c/bitfields2/test.desc b/regression/ansi-c/bitfields2/test.desc new file mode 100644 index 00000000000..1fd6f840e01 --- /dev/null +++ b/regression/ansi-c/bitfields2/test.desc @@ -0,0 +1,9 @@ +CORE +main.c + +zero-width bit-field with declarator not permitted$ +CONVERSION ERROR +^EXIT=(64|1)$ +^SIGNAL=0$ +-- +^warning: ignoring diff --git a/src/ansi-c/c_typecheck_type.cpp b/src/ansi-c/c_typecheck_type.cpp index 42fdd048577..bde69b633b7 100644 --- a/src/ansi-c/c_typecheck_type.cpp +++ b/src/ansi-c/c_typecheck_type.cpp @@ -964,6 +964,16 @@ void c_typecheck_baset::typecheck_compound_body( throw 0; } + if( + new_component.type().id() == ID_c_bit_field && + to_c_bit_field_type(new_component.type()).get_width() == 0 && + !new_component.get_name().empty()) + { + throw invalid_source_file_exceptiont{ + "zero-width bit-field with declarator not permitted", + source_location}; + } + components.push_back(new_component); } }