Skip to content

Commit e5ccd66

Browse files
committed
[clang][sema] Enable first-class bool support for C2x
Implement N2395 for C2x. This also covers adding "bool", which is part of N2394. Differential Revision: https://reviews.llvm.org/D120244
1 parent e5c1a90 commit e5ccd66

File tree

5 files changed

+72
-8
lines changed

5 files changed

+72
-8
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ C2x Feature Support
110110
-------------------
111111

112112
- Implemented `WG14 N2674 The noreturn attribute <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2764.pdf>`_.
113+
- Implemented `WG14 N2935 Make false and true first-class language features <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2935.pdf>`_.
113114

114115
C++ Language Changes in Clang
115116
-----------------------------

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3249,8 +3249,8 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
32493249

32503250
Opts.RenderScript = IK.getLanguage() == Language::RenderScript;
32513251

3252-
// OpenCL and C++ both have bool, true, false keywords.
3253-
Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
3252+
// OpenCL, C++ and C2x have bool, true, false keywords.
3253+
Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C2x;
32543254

32553255
// OpenCL has half keyword
32563256
Opts.Half = Opts.OpenCL;

clang/lib/Headers/stdbool.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@
1010
#ifndef __STDBOOL_H
1111
#define __STDBOOL_H
1212

13-
/* Don't define bool, true, and false in C++, except as a GNU extension. */
14-
#ifndef __cplusplus
13+
#define __bool_true_false_are_defined 1
14+
15+
#if __STDC_VERSION__ > 201710L
16+
#if !defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS)
17+
#warning "the <stdbool.h> header is deprecated in C2x"
18+
#endif /* !defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS) */
19+
#elif !defined(__cplusplus)
1520
#define bool _Bool
1621
#define true 1
1722
#define false 0
@@ -20,12 +25,10 @@
2025
#define _Bool bool
2126
#if __cplusplus < 201103L
2227
/* For C++98, define bool, false, true as a GNU extension. */
23-
#define bool bool
28+
#define bool bool
2429
#define false false
25-
#define true true
30+
#define true true
2631
#endif
2732
#endif
2833

29-
#define __bool_true_false_are_defined 1
30-
3134
#endif /* __STDBOOL_H */

clang/test/Headers/stdbool.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %clang_cc1 -fgnuc-version=4.2.1 -std=c11 -E -dM %s 2>&1 | FileCheck --check-prefix=CHECK-C11 %s
2+
// RUN: %clang_cc1 -fgnuc-version=4.2.1 -std=c2x -E -dM %s 2>&1 | FileCheck --check-prefix=CHECK-C2X %s
3+
// RUN: %clang_cc1 -fgnuc-version=4.2.1 -std=c2x -E -dM -D_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS %s 2>&1 | FileCheck --check-prefix=CHECK-C2X-CRT %s
4+
5+
#include <stdbool.h>
6+
7+
// CHECK-C11: #define bool _Bool
8+
// CHECK-C11: #define false 0
9+
// CHECK-C11: #define true 1
10+
11+
// CHECK-C2X: warning "the <stdbool.h> header is deprecated
12+
// CHECK-C2X-NOT: #define bool
13+
// CHECK-C2X-NOT: #define true
14+
// CHECK-C2X-NOT: #define falsea
15+
16+
// CHECK-C2X-CRT-NOT: warning "the <stdbool.h> header is deprecated
17+
// CHECK-C2X-CRT-NOT: #define bool
18+
// CHECK-C2X-CRT-NOT: #define true
19+
// CHECK-C2X-CRT-NOT: #define false

clang/test/Sema/c2x-bool.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: %clang_cc1 -std=c2x -fsyntax-only -verify %s
2+
3+
_Static_assert(_Generic(true, _Bool : 1, default: 0));
4+
_Static_assert(_Generic(false, _Bool : 1, default: 0));
5+
6+
_Static_assert(_Generic(true, bool : 1, default: 0));
7+
_Static_assert(_Generic(false, bool : 1, default: 0));
8+
9+
_Static_assert(_Generic(true, bool : true, default: false));
10+
_Static_assert(_Generic(false, bool : true, default: false));
11+
12+
_Static_assert(true == (bool)+1);
13+
_Static_assert(false == (bool)+0);
14+
15+
_Static_assert(_Generic(+true, bool : 0, unsigned int : 0, signed int : 1, default : 0));
16+
17+
struct S {
18+
bool b : 1;
19+
} s;
20+
_Static_assert(_Generic(+s.b, bool : 0, unsigned int : 0, signed int : 1, default : 0));
21+
22+
static void *f = false; // expected-warning {{to null from a constant boolean expression}}
23+
static int one = true;
24+
static int zero = false;
25+
26+
static void do_work() {
27+
char *str = "Foo";
28+
str[false] = 'f';
29+
str[true] = 'f';
30+
31+
char c1[true];
32+
char c2[false];
33+
}
34+
35+
#if true != 1
36+
#error true should be 1 in the preprocessor
37+
#endif
38+
39+
#if false != 0
40+
#error false should be 0 in the preprocessor
41+
#endif

0 commit comments

Comments
 (0)