Skip to content

Commit 0077048

Browse files
authored
[C23] Fixed the value of BOOL_WIDTH (#117364)
The standard mandates that this returns the width of the type, which is the number of bits in the value. For bool, that's required to be `1` explicitly. Fixes #117348
1 parent 362d8fb commit 0077048

File tree

6 files changed

+43
-6
lines changed

6 files changed

+43
-6
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ C23 Feature Support
332332

333333
- Clang now supports `N3029 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3029.htm>`_ Improved Normal Enumerations.
334334
- Clang now officially supports `N3030 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3030.htm>`_ Enhancements to Enumerations. Clang already supported it as an extension, so there were no changes to compiler behavior.
335+
- Fixed the value of ``BOOL_WIDTH`` in ``<limits.h>`` to return ``1``
336+
explicitly, as mandated by the standard. Fixes #GH117348
335337

336338
Non-comprehensive list of changes in this release
337339
-------------------------------------------------

clang/lib/Frontend/InitPreprocessor.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,15 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
11031103
assert(TI.getCharWidth() == 8 && "Only support 8-bit char so far");
11041104
Builder.defineMacro("__CHAR_BIT__", Twine(TI.getCharWidth()));
11051105

1106-
Builder.defineMacro("__BOOL_WIDTH__", Twine(TI.getBoolWidth()));
1106+
// The macro is specifying the number of bits in the width, not the number of
1107+
// bits the object requires for its in-memory representation, which is what
1108+
// getBoolWidth() will return. The bool/_Bool data type is only ever one bit
1109+
// wide. See C23 6.2.6.2p2 for the rules in C. Note that
1110+
// C++23 [basic.fundamental]p10 allows an implementation-defined value
1111+
// representation for bool; when lowering to LLVM, Clang represents bool as an
1112+
// i8 in memory but as an i1 when the value is needed, so '1' is also correct
1113+
// for C++.
1114+
Builder.defineMacro("__BOOL_WIDTH__", "1");
11071115
Builder.defineMacro("__SHRT_WIDTH__", Twine(TI.getShortWidth()));
11081116
Builder.defineMacro("__INT_WIDTH__", Twine(TI.getIntWidth()));
11091117
Builder.defineMacro("__LONG_WIDTH__", Twine(TI.getLongWidth()));

clang/test/C/C23/n2412.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %clang_cc1 -verify -std=c23 -ffreestanding %s
2+
3+
/* WG14 N2412: Clang 14
4+
* Two's complement sign representation
5+
*/
6+
// expected-no-diagnostics
7+
8+
#include <limits.h>
9+
10+
// GH117348 -- BOOL_WIDTH was accidentally expanding to the number of bits in
11+
// the object representation (8) rather than the number of bits in the value
12+
// representation (1).
13+
static_assert(BOOL_WIDTH == 1);
14+
15+
// Validate the other macro requirements.
16+
static_assert(CHAR_WIDTH == SCHAR_WIDTH);
17+
static_assert(CHAR_WIDTH == UCHAR_WIDTH);
18+
static_assert(CHAR_WIDTH == CHAR_BIT);
19+
20+
static_assert(USHRT_WIDTH >= 16);
21+
static_assert(UINT_WIDTH >= 16);
22+
static_assert(ULONG_WIDTH >= 32);
23+
static_assert(ULLONG_WIDTH >= 64);
24+
static_assert(BITINT_MAXWIDTH >= ULLONG_WIDTH);
25+
26+
static_assert(MB_LEN_MAX >= 1);
27+

clang/test/Preprocessor/init-aarch64.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
// AARCH64: #define __BIGGEST_ALIGNMENT__ 16
4545
// AARCH64_BE-NEXT: #define __BIG_ENDIAN__ 1
4646
// AARCH64-NEXT: #define __BITINT_MAXWIDTH__ 128
47-
// AARCH64-NEXT: #define __BOOL_WIDTH__ 8
47+
// AARCH64-NEXT: #define __BOOL_WIDTH__ 1
4848
// AARCH64_BE-NEXT: #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
4949
// AARCH64_LE-NEXT: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
5050
// AARCH64-NEXT: #define __CHAR16_TYPE__ unsigned short
@@ -785,7 +785,7 @@
785785
// ARM64EC-MSVC: #define __ATOMIC_SEQ_CST 5
786786
// ARM64EC-MSVC: #define __BIGGEST_ALIGNMENT__ 16
787787
// ARM64EC-MSVC: #define __BITINT_MAXWIDTH__ 128
788-
// ARM64EC-MSVC: #define __BOOL_WIDTH__ 8
788+
// ARM64EC-MSVC: #define __BOOL_WIDTH__ 1
789789
// ARM64EC-MSVC: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
790790
// ARM64EC-MSVC: #define __CHAR16_TYPE__ unsigned short
791791
// ARM64EC-MSVC: #define __CHAR32_TYPE__ unsigned int

clang/test/Preprocessor/init-loongarch.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
// LA32-NEXT: #define __ATOMIC_SEQ_CST 5
2626
// LA32: #define __BIGGEST_ALIGNMENT__ 16
2727
// LA32: #define __BITINT_MAXWIDTH__ 128
28-
// LA32: #define __BOOL_WIDTH__ 8
28+
// LA32: #define __BOOL_WIDTH__ 1
2929
// LA32: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
3030
// LA32: #define __CHAR16_TYPE__ unsigned short
3131
// LA32: #define __CHAR32_TYPE__ unsigned int
@@ -346,7 +346,7 @@
346346
// LA64-NEXT: #define __ATOMIC_SEQ_CST 5
347347
// LA64: #define __BIGGEST_ALIGNMENT__ 16
348348
// LA64: #define __BITINT_MAXWIDTH__ 128
349-
// LA64: #define __BOOL_WIDTH__ 8
349+
// LA64: #define __BOOL_WIDTH__ 1
350350
// LA64: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
351351
// LA64: #define __CHAR16_TYPE__ unsigned short
352352
// LA64: #define __CHAR32_TYPE__ unsigned int

clang/test/Preprocessor/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1617,7 +1617,7 @@
16171617
// WEBASSEMBLY-NEXT:#define __ATOMIC_SEQ_CST 5
16181618
// WEBASSEMBLY-NEXT:#define __BIGGEST_ALIGNMENT__ 16
16191619
// WEBASSEMBLY-NEXT:#define __BITINT_MAXWIDTH__ 128
1620-
// WEBASSEMBLY-NEXT:#define __BOOL_WIDTH__ 8
1620+
// WEBASSEMBLY-NEXT:#define __BOOL_WIDTH__ 1
16211621
// WEBASSEMBLY-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
16221622
// WEBASSEMBLY-NEXT:#define __CHAR16_TYPE__ unsigned short
16231623
// WEBASSEMBLY-NEXT:#define __CHAR32_TYPE__ unsigned int

0 commit comments

Comments
 (0)