<div dir="ltr">Do I just edit the HTML file directly?<div>Or is it generated by something?</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 24, 2019 at 3:35 PM Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Thanks! Can you update cxx_status.html to mark P0595R2 as done?<br>
<br>
On Tue, 23 Apr 2019 at 19:21, Eric Fiselier via cfe-commits<br>
<<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br>
><br>
> Author: ericwf<br>
> Date: Tue Apr 23 19:23:30 2019<br>
> New Revision: 359067<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=359067&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=359067&view=rev</a><br>
> Log:<br>
> [Builtins] Implement __builtin_is_constant_evaluated for use in C++2a<br>
><br>
> Summary:<br>
> This patch implements `__builtin_is_constant_evaluated` as specifier by [P0595R2](<a href="https://wg21.link/p0595r2" rel="noreferrer" target="_blank">https://wg21.link/p0595r2</a>). It is built on the back of Bill Wendling's work for `__builtin_constant_p()`.<br>
><br>
> More tests to come, but early feedback is appreciated.<br>
><br>
> I plan to implement warnings for common mis-usages like those belowe in a following patch:<br>
> ```<br>
> void foo(int x) {<br>
>   if constexpr (std::is_constant_evaluated())) { // condition is always `true`. Should use plain `if` instead.<br>
>    foo_constexpr(x);<br>
>   } else {<br>
>     foo_runtime(x);<br>
>   }<br>
> }<br>
> ```<br>
><br>
><br>
><br>
> Reviewers: rsmith, MaskRay, bruno, void<br>
><br>
> Reviewed By: rsmith<br>
><br>
> Subscribers: dexonsmith, zoecarver, fdeazeve, kristina, cfe-commits<br>
><br>
> Differential Revision: <a href="https://reviews.llvm.org/D55500" rel="noreferrer" target="_blank">https://reviews.llvm.org/D55500</a><br>
><br>
> Added:<br>
>     cfe/trunk/test/CodeGenCXX/builtin-is-constant-evaluated.cpp<br>
>     cfe/trunk/test/SemaCXX/builtin-is-constant-evaluated.cpp<br>
> Modified:<br>
>     cfe/trunk/include/clang/Basic/Builtins.def<br>
>     cfe/trunk/lib/AST/ExprConstant.cpp<br>
>     cfe/trunk/lib/Basic/Builtins.cpp<br>
>     cfe/trunk/lib/CodeGen/CGDecl.cpp<br>
>     cfe/trunk/test/Sema/builtins.c<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/Builtins.def<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=359067&r1=359066&r2=359067&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=359067&r1=359066&r2=359067&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/Builtins.def (original)<br>
> +++ cfe/trunk/include/clang/Basic/Builtins.def Tue Apr 23 19:23:30 2019<br>
> @@ -500,6 +500,7 @@ BUILTIN(__builtin_vsprintf, "ic*cC*a", "<br>
>  BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")<br>
>  BUILTIN(__builtin_thread_pointer, "v*", "nc")<br>
>  BUILTIN(__builtin_launder, "v*v*", "nt")<br>
> +LANGBUILTIN(__builtin_is_constant_evaluated, "b", "n", CXX_LANG)<br>
><br>
>  // GCC exception builtins<br>
>  BUILTIN(__builtin_eh_return, "vzv*", "r") // FIXME: Takes intptr_t, not size_t!<br>
><br>
> Modified: cfe/trunk/lib/AST/ExprConstant.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=359067&r1=359066&r2=359067&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=359067&r1=359066&r2=359067&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)<br>
> +++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Apr 23 19:23:30 2019<br>
> @@ -8279,6 +8279,9 @@ bool IntExprEvaluator::VisitBuiltinCallE<br>
>      return Success(false, E);<br>
>    }<br>
><br>
> +  case Builtin::BI__builtin_is_constant_evaluated:<br>
> +    return Success(Info.InConstantContext, E);<br>
> +<br>
>    case Builtin::BI__builtin_ctz:<br>
>    case Builtin::BI__builtin_ctzl:<br>
>    case Builtin::BI__builtin_ctzll:<br>
> @@ -11139,6 +11142,7 @@ bool Expr::EvaluateAsConstantExpr(EvalRe<br>
>    EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;<br>
>    EvalInfo Info(Ctx, Result, EM);<br>
>    Info.InConstantContext = true;<br>
> +<br>
>    if (!::Evaluate(Result.Val, Info, this))<br>
>      return false;<br>
><br>
><br>
> Modified: cfe/trunk/lib/Basic/Builtins.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Builtins.cpp?rev=359067&r1=359066&r2=359067&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Builtins.cpp?rev=359067&r1=359066&r2=359067&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Basic/Builtins.cpp (original)<br>
> +++ cfe/trunk/lib/Basic/Builtins.cpp Tue Apr 23 19:23:30 2019<br>
> @@ -75,9 +75,12 @@ bool Builtin::Context::builtinIsSupporte<br>
>    bool OclCUnsupported = !LangOpts.OpenCL &&<br>
>                           (BuiltinInfo.Langs & ALL_OCLC_LANGUAGES);<br>
>    bool OpenMPUnsupported = !LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG;<br>
> +  bool CPlusPlusUnsupported =<br>
> +      !LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG;<br>
>    return !BuiltinsUnsupported && !MathBuiltinsUnsupported && !OclCUnsupported &&<br>
>           !OclC1Unsupported && !OclC2Unsupported && !OpenMPUnsupported &&<br>
> -         !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported;<br>
> +         !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported &&<br>
> +         !CPlusPlusUnsupported;<br>
>  }<br>
><br>
>  /// initializeBuiltins - Mark the identifiers for all the builtins with their<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=359067&r1=359066&r2=359067&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=359067&r1=359066&r2=359067&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Apr 23 19:23:30 2019<br>
> @@ -1783,7 +1783,8 @@ void CodeGenFunction::EmitAutoVarInit(co<br>
>    }<br>
><br>
>    llvm::Constant *constant = nullptr;<br>
> -  if (emission.IsConstantAggregate || D.isConstexpr()) {<br>
> +  if (emission.IsConstantAggregate || D.isConstexpr() ||<br>
> +      D.isUsableInConstantExpressions(getContext())) {<br>
>      assert(!capturedByInit && "constant init contains a capturing block?");<br>
>      constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(D);<br>
>      if (constant && trivialAutoVarInit !=<br>
><br>
> Added: cfe/trunk/test/CodeGenCXX/builtin-is-constant-evaluated.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/builtin-is-constant-evaluated.cpp?rev=359067&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/builtin-is-constant-evaluated.cpp?rev=359067&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CodeGenCXX/builtin-is-constant-evaluated.cpp (added)<br>
> +++ cfe/trunk/test/CodeGenCXX/builtin-is-constant-evaluated.cpp Tue Apr 23 19:23:30 2019<br>
> @@ -0,0 +1,133 @@<br>
> +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -std=c++2a -o %t.ll<br>
> +// RUN: FileCheck -check-prefix=CHECK-FN-CG -input-file=%t.ll %s<br>
> +// RUN: FileCheck -check-prefix=CHECK-STATIC -input-file=%t.ll %s<br>
> +// RUN: FileCheck -check-prefix=CHECK-DYN -input-file=%t.ll %s<br>
> +// RUN: FileCheck -check-prefix=CHECK-ARR -input-file=%t.ll %s<br>
> +// RUN: FileCheck -check-prefix=CHECK-FOLD -input-file=%t.ll %s<br>
> +<br>
> +using size_t = decltype(sizeof(int));<br>
> +<br>
> +#define CONSTINIT __attribute__((require_constant_initialization))<br>
> +<br>
> +extern "C" [[noreturn]] void BOOM();<br>
> +extern "C" void OK();<br>
> +extern "C" size_t RANDU();<br>
> +<br>
> +namespace std {<br>
> +inline constexpr bool is_constant_evaluated() noexcept {<br>
> +  return __builtin_is_constant_evaluated();<br>
> +}<br>
> +} // namespace std<br>
> +<br>
> +// CHECK-FN-CG-LABEL: define zeroext i1 @_Z3foov()<br>
> +// CHECK-FN-CG: ret i1 false<br>
> +bool foo() {<br>
> +  return __builtin_is_constant_evaluated();<br>
> +}<br>
> +<br>
> +// CHECK-FN-CG-LABEL: define linkonce_odr i32 @_Z1fv()<br>
> +constexpr int f() {<br>
> +  // CHECK-FN-CG: store i32 13, i32* %n, align 4<br>
> +  // CHECK-FN-CG: store i32 17, i32* %m, align 4<br>
> +  // CHECK-FN-CG:  %1 = load i32, i32* %m, align 4<br>
> +  // CHECK-FN-CG: %add = add nsw i32 %1, 13<br>
> +  // CHECK-FN-CG: ret i32 %add<br>
> +  const int n = __builtin_is_constant_evaluated() && std::is_constant_evaluated() ? 13 : 17; // n == 13<br>
> +  int m = __builtin_is_constant_evaluated() ? 13 : 17;       // m might be 13 or 17 (see below)<br>
> +  char arr[n] = {};                                          // char[13]<br>
> +  return m + int(sizeof(arr));<br>
> +}<br>
> +<br>
> +// CHECK-STATIC-DAG: @p = global i32 26,<br>
> +CONSTINIT int p = f(); // f().m == 13; initialized to 26<br>
> +// CHECK-STATIC-DAG: @p2 = global i32 26,<br>
> +int p2 = f(); // same result without CONSTINIT<br>
> +<br>
> +// CHECK-DYN-LABEL: define internal void @__cxx_global_var_init()<br>
> +// CHECK-DYN: %0 = load i32, i32* @p, align 4<br>
> +// CHECK-DYN-NEXT: %call = call i32 @_Z1fv()<br>
> +// CHECK-DYN-NEXT: %add = add nsw i32 %0, %call<br>
> +// CHECK-DYN-NEXT: store i32 %add, i32* @q, align 4<br>
> +// CHECK-DYN-NEXT: ret void<br>
> +int q = p + f(); // m == 17 for this call; initialized to 56<br>
> +<br>
> +int y;<br>
> +<br>
> +// CHECK-STATIC-DAG: @b = global i32 2,<br>
> +CONSTINIT int b = __builtin_is_constant_evaluated() ? 2 : y; // static initialization to 2<br>
> +<br>
> +// CHECK-DYN-LABEL: define internal void @__cxx_global_var_init.1()<br>
> +// CHECK-DYN: %0 = load i32, i32* @y, align 4<br>
> +// CHECK-DYN: %1 = load i32, i32* @y, align 4<br>
> +// CHECK-DYN-NEXT: %add = add<br>
> +// CHECK-DYN-NEXT: store i32 %add, i32* @c,<br>
> +int c = y + (__builtin_is_constant_evaluated() ? 2 : y); // dynamic initialization to y+y<br>
> +<br>
> +// CHECK-DYN-LABEL: define internal void @__cxx_global_var_init.2()<br>
> +// CHECK-DYN: store i32 1, i32* @_ZL1a, align 4<br>
> +// CHECK-DYN-NEXT: ret void<br>
> +const int a = __builtin_is_constant_evaluated() ? y : 1; // dynamic initialization to 1<br>
> +const int *a_sink = &a;<br>
> +<br>
> +// CHECK-ARR-LABEL: define void @_Z13test_arr_exprv<br>
> +void test_arr_expr() {<br>
> +  // CHECK-ARR: %x1 = alloca [101 x i8],<br>
> +  char x1[std::is_constant_evaluated() && __builtin_is_constant_evaluated() ? 101 : 1];<br>
> +<br>
> +  // CHECK-ARR: %x2 = alloca [42 x i8],<br>
> +  char x2[std::is_constant_evaluated() && __builtin_is_constant_evaluated() ? 42 : RANDU()];<br>
> +<br>
> +  // CHECK-ARR: call i8* @llvm.stacksave()<br>
> +  // CHECK-ARR: %vla = alloca i8, i64 13,<br>
> +  char x3[std::is_constant_evaluated() || __builtin_is_constant_evaluated() ? RANDU() : 13];<br>
> +}<br>
> +<br>
> +// CHECK-ARR-LABEL: define void @_Z17test_new_arr_exprv<br>
> +void test_new_arr_expr() {<br>
> +  // CHECK-ARR: call i8* @_Znam(i64 17)<br>
> +  new char[std::is_constant_evaluated() || __builtin_is_constant_evaluated() ? 1 : 17];<br>
> +}<br>
> +<br>
> +// CHECK-FOLD-LABEL: @_Z31test_constant_initialized_locali(<br>
> +bool test_constant_initialized_local(int k) {<br>
> +  // CHECK-FOLD: store i8 1, i8* %n,<br>
> +  // CHECK-FOLD: store volatile i8* %n, i8** %p,<br>
> +  const bool n = __builtin_is_constant_evaluated() && std::is_constant_evaluated();<br>
> +  const bool *volatile p = &n;<br>
> +  return *p;<br>
> +}<br>
> +<br>
> +// CHECK-FOLD-LABEL: define void @_Z21test_ir_constant_foldv()<br>
> +void test_ir_constant_fold() {<br>
> +  // CHECK-FOLD-NEXT: entry:<br>
> +  // CHECK-FOLD-NEXT: call void @OK()<br>
> +  // CHECK-FOLD-NEXT: call void @OK()<br>
> +  // CHECK-FOLD-NEXT: ret void<br>
> +  if (std::is_constant_evaluated()) {<br>
> +    BOOM();<br>
> +  } else {<br>
> +    OK();<br>
> +  }<br>
> +  std::is_constant_evaluated() ? BOOM() : OK();<br>
> +}<br>
> +<br>
> +// CHECK-STATIC-DAG: @ir = constant i32* @i_constant,<br>
> +int i_constant;<br>
> +int i_not_constant;<br>
> +int &ir = __builtin_is_constant_evaluated() ? i_constant : i_not_constant;<br>
> +<br>
> +// CHECK-FOLD-LABEL: @_Z35test_ref_initialization_local_scopev()<br>
> +void test_ref_initialization_local_scope() {<br>
> +  const int i_constant = 42;<br>
> +  const int i_non_constant = 101;<br>
> +  // CHECK-FOLD: store i32* %i_non_constant, i32** %r,<br>
> +  const int &r = __builtin_is_constant_evaluated() ? i_constant : i_non_constant;<br>
> +}<br>
> +<br>
> +// CHECK-FOLD-LABEL: @_Z22test_ref_to_static_varv()<br>
> +void test_ref_to_static_var() {<br>
> +  static int i_constant = 42;<br>
> +  static int i_non_constant = 101;<br>
> +  // CHECK-FOLD: store i32* @_ZZ22test_ref_to_static_varvE10i_constant, i32** %r,<br>
> +  int &r = __builtin_is_constant_evaluated() ? i_constant : i_non_constant;<br>
> +}<br>
> \ No newline at end of file<br>
><br>
> Modified: cfe/trunk/test/Sema/builtins.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtins.c?rev=359067&r1=359066&r2=359067&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtins.c?rev=359067&r1=359066&r2=359067&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/Sema/builtins.c (original)<br>
> +++ cfe/trunk/test/Sema/builtins.c Tue Apr 23 19:23:30 2019<br>
> @@ -314,3 +314,9 @@ void test23() {<br>
>    memcpy(buf, src, 11); // expected-warning{{'memcpy' will always overflow; destination buffer has size 10, but size argument is 11}}<br>
>    my_memcpy(buf, src, 11); // expected-warning{{'memcpy' will always overflow; destination buffer has size 10, but size argument is 11}}<br>
>  }<br>
> +<br>
> +// Test that __builtin_is_constant_evaluated() is not allowed in C<br>
> +int test_cxx_builtin() {<br>
> +  // expected-error@+1 {{use of unknown builtin '__builtin_is_constant_evaluated'}}<br>
> +  return __builtin_is_constant_evaluated();<br>
> +}<br>
><br>
> Added: cfe/trunk/test/SemaCXX/builtin-is-constant-evaluated.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-is-constant-evaluated.cpp?rev=359067&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-is-constant-evaluated.cpp?rev=359067&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/SemaCXX/builtin-is-constant-evaluated.cpp (added)<br>
> +++ cfe/trunk/test/SemaCXX/builtin-is-constant-evaluated.cpp Tue Apr 23 19:23:30 2019<br>
> @@ -0,0 +1,121 @@<br>
> +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu<br>
> +<br>
> +using size_t = decltype(sizeof(int));<br>
> +<br>
> +namespace std {<br>
> +inline constexpr bool is_constant_evaluated() noexcept {<br>
> +  return __builtin_is_constant_evaluated();<br>
> +}<br>
> +} // namespace std<br>
> +<br>
> +extern int dummy; // expected-note 1+ {{declared here}}<br>
> +<br>
> +static_assert(__builtin_is_constant_evaluated());<br>
> +static_assert(noexcept(__builtin_is_constant_evaluated()));<br>
> +<br>
> +constexpr bool b = __builtin_is_constant_evaluated();<br>
> +static_assert(b);<br>
> +<br>
> +const int n = __builtin_is_constant_evaluated() ? 4 : dummy;<br>
> +static_assert(n == 4);<br>
> +constexpr int cn = __builtin_is_constant_evaluated() ? 11 : dummy;<br>
> +static_assert(cn == 11);<br>
> +// expected-error@+1 {{'bn' must be initialized by a constant expression}}<br>
> +constexpr int bn = __builtin_is_constant_evaluated() ? dummy : 42; // expected-note {{non-const variable 'dummy' is not allowed}}<br>
> +<br>
> +const int n2 = __builtin_is_constant_evaluated() ? dummy : 42; // expected-note {{declared here}}<br>
> +static_assert(n2 == 42);                                       // expected-error {{static_assert expression is not an integral constant}}<br>
> +// expected-note@-1 {{initializer of 'n2' is not a constant expression}}<br>
> +<br>
> +template <bool V, bool Default = std::is_constant_evaluated()><br>
> +struct Templ { static_assert(V); static_assert(Default); };<br>
> +Templ<__builtin_is_constant_evaluated()> x; // type X<true><br>
> +<br>
> +template <class T><br>
> +void test_if_constexpr() {<br>
> +  if constexpr (__builtin_is_constant_evaluated()) {<br>
> +    static_assert(__is_same(T, int));<br>
> +  } else {<br>
> +    using Test = typename T::DOES_NOT_EXIST;<br>
> +  }<br>
> +}<br>
> +template void test_if_constexpr<int>();<br>
> +<br>
> +void test_array_decl() {<br>
> +  char x[__builtin_is_constant_evaluated() + std::is_constant_evaluated()];<br>
> +  static_assert(sizeof(x) == 2, "");<br>
> +}<br>
> +<br>
> +void test_case_stmt(int x) {<br>
> +  switch (x) {<br>
> +  case 0:                                                                // OK<br>
> +  case __builtin_is_constant_evaluated():                                // expected-note {{previous case}}<br>
> +  case std::is_constant_evaluated() + __builtin_is_constant_evaluated(): // expected-note {{previous case}}<br>
> +  case 1:                                                                // expected-error {{duplicate case value '1'}}<br>
> +  case 2:                                                                // expected-error {{duplicate case value '2'}}<br>
> +    break;<br>
> +  }<br>
> +}<br>
> +<br>
> +constexpr size_t good_array_size() {<br>
> +  return std::is_constant_evaluated() ? 42 : static_cast<size_t>(-1);<br>
> +}<br>
> +<br>
> +constexpr size_t bad_array_size() {<br>
> +  return std::is_constant_evaluated() ? static_cast<size_t>(-1) : 13;<br>
> +}<br>
> +<br>
> +template <class T><br>
> +constexpr T require_constexpr(T v) {<br>
> +  if (!std::is_constant_evaluated())<br>
> +    throw "BOOM";<br>
> +  return v;<br>
> +}<br>
> +<br>
> +void test_new_expr() {<br>
> +  constexpr size_t TooLarge = -1;<br>
> +  auto *x = new int[std::is_constant_evaluated() ? 1 : TooLarge];      // expected-error {{array is too large}}<br>
> +  auto *x2 = new int[std::is_constant_evaluated() ? TooLarge : 1];     // OK<br>
> +  auto *y = new int[1][std::is_constant_evaluated() ? TooLarge : 1]{}; // expected-error {{array is too large}}<br>
> +  auto *y2 = new int[1][require_constexpr(42)];<br>
> +}<br>
> +<br>
> +void test_alignas_operand() {<br>
> +  alignas(std::is_constant_evaluated() ? 8 : 2) char dummy;<br>
> +  static_assert(__alignof(dummy) == 8);<br>
> +}<br>
> +<br>
> +void test_static_assert_operand() {<br>
> +  static_assert(std::is_constant_evaluated(), "");<br>
> +}<br>
> +<br>
> +void test_enumerator() {<br>
> +  enum MyEnum {<br>
> +    ZERO = 0,<br>
> +    ONE = std::is_constant_evaluated()<br>
> +  };<br>
> +  static_assert(ONE == 1, "");<br>
> +}<br>
> +<br>
> +struct TestBitfieldWidth {<br>
> +  unsigned Bits : std::is_constant_evaluated();<br>
> +};<br>
> +<br>
> +void test_operand_of_noexcept_fn() noexcept(std::is_constant_evaluated());<br>
> +static_assert(noexcept(test_operand_of_noexcept_fn()), "");<br>
> +<br>
> +<br>
> +namespace test_ref_initialization {<br>
> +int x;<br>
> +int y;<br>
> +int &r = __builtin_is_constant_evaluated() ? x : y;<br>
> +static_assert(&r == &x);<br>
> +<br>
> +} // namespace test_ref_initialization<br>
> +<br>
> +#if defined(__cpp_conditional_explicit)<br>
> +struct TestConditionalExplicit {<br>
> +  explicit(__builtin_is_constant_evaluated()) TestConditionalExplicit(int) {}<br>
> +};<br>
> +TestConditionalExplicit e = 42;<br>
> +#endif<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>