Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -111,6 +111,7 @@ - Implemented `WG14 N2674 The noreturn attribute `_. - Implemented `WG14 N2418 Adding the u8 character prefix `_. +- Implemented `WG14 N2935 Make false and true first-class language features `_. C++ Language Changes in Clang ----------------------------- Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -3249,8 +3249,8 @@ Opts.RenderScript = IK.getLanguage() == Language::RenderScript; - // OpenCL and C++ both have bool, true, false keywords. - Opts.Bool = Opts.OpenCL || Opts.CPlusPlus; + // OpenCL, C++ and C2x have bool, true, false keywords. + Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C2x; // OpenCL has half keyword Opts.Half = Opts.OpenCL; Index: clang/lib/Headers/stdbool.h =================================================================== --- clang/lib/Headers/stdbool.h +++ clang/lib/Headers/stdbool.h @@ -10,6 +10,8 @@ #ifndef __STDBOOL_H #define __STDBOOL_H +/* true, false and bool are first-class keywords in C2x */ +#if __STDC_VERSION__ < 202000L /* Don't define bool, true, and false in C++, except as a GNU extension. */ #ifndef __cplusplus #define bool _Bool @@ -20,9 +22,10 @@ #define _Bool bool #if __cplusplus < 201103L /* For C++98, define bool, false, true as a GNU extension. */ -#define bool bool +#define bool bool #define false false -#define true true +#define true true +#endif #endif #endif Index: clang/test/Sema/c2x-bool.c =================================================================== --- /dev/null +++ clang/test/Sema/c2x-bool.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -std=c2x -fsyntax-only -verify %s + +_Static_assert(_Generic(true, _Bool : 1, default: 0)); +_Static_assert(_Generic(false, _Bool : 1, default: 0)); + +_Static_assert(_Generic(true, bool : 1, default: 0)); +_Static_assert(_Generic(false, bool : 1, default: 0)); + +_Static_assert(_Generic(true, bool : true, default: false)); +_Static_assert(_Generic(false, bool : true, default: false)); + +_Static_assert(true == (bool)+1); +_Static_assert(false == (bool)+0); + +_Static_assert(_Generic(+true, bool : 0, unsigned int : 0, signed int : 1, default : 0)); + +struct S { + bool b : 1; +} s; +_Static_assert(_Generic(+s.b, bool : 0, unsigned int : 0, signed int : 1, default : 0)); + +static void *f = false; // expected-warning {{to null from a constant boolean expression}} +static int one = true; +static int zero = false; + +static void do_work() { + char *str = "Foo"; + str[false] = 'f'; + str[true] = 'f'; + + char c1[true]; + char c2[false]; +} + +#if true != 1 +#error true should be 1 in the preprocessor +#endif + +#if false != 0 +#error false should be 0 in the preprocessor +#endif