1 // RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu 2 3 using size_t = decltype(sizeof(int)); 4 5 namespace std { is_constant_evaluated()6inline constexpr bool is_constant_evaluated() noexcept { 7 return __builtin_is_constant_evaluated(); 8 } 9 } // namespace std 10 11 extern int dummy; // expected-note 1+ {{declared here}} 12 13 static_assert(__builtin_is_constant_evaluated()); 14 static_assert(noexcept(__builtin_is_constant_evaluated())); 15 16 constexpr bool b = __builtin_is_constant_evaluated(); 17 static_assert(b); 18 19 const int n = __builtin_is_constant_evaluated() ? 4 : dummy; 20 static_assert(n == 4); 21 constexpr int cn = __builtin_is_constant_evaluated() ? 11 : dummy; 22 static_assert(cn == 11); 23 // expected-error@+1 {{'bn' must be initialized by a constant expression}} 24 constexpr int bn = __builtin_is_constant_evaluated() ? dummy : 42; // expected-note {{non-const variable 'dummy' is not allowed}} 25 26 const int n2 = __builtin_is_constant_evaluated() ? dummy : 42; // expected-note {{declared here}} 27 static_assert(n2 == 42); // expected-error {{static_assert expression is not an integral constant}} 28 // expected-note@-1 {{initializer of 'n2' is not a constant expression}} 29 30 template <bool V, bool Default = std::is_constant_evaluated()> 31 struct Templ { static_assert(V); static_assert(Default); }; 32 Templ<__builtin_is_constant_evaluated()> x; // type X<true> 33 34 template <class T> test_if_constexpr()35void test_if_constexpr() { 36 if constexpr (__builtin_is_constant_evaluated()) { 37 static_assert(__is_same(T, int)); 38 } else { 39 using Test = typename T::DOES_NOT_EXIST; 40 } 41 } 42 template void test_if_constexpr<int>(); 43 test_array_decl()44void test_array_decl() { 45 char x[__builtin_is_constant_evaluated() + std::is_constant_evaluated()]; 46 static_assert(sizeof(x) == 2, ""); 47 } 48 test_case_stmt(int x)49void test_case_stmt(int x) { 50 switch (x) { 51 case 0: // OK 52 case __builtin_is_constant_evaluated(): // expected-note {{previous case}} 53 case std::is_constant_evaluated() + __builtin_is_constant_evaluated(): // expected-note {{previous case}} 54 case 1: // expected-error {{duplicate case value '1'}} 55 case 2: // expected-error {{duplicate case value '2'}} 56 break; 57 } 58 } 59 good_array_size()60constexpr size_t good_array_size() { 61 return std::is_constant_evaluated() ? 42 : static_cast<size_t>(-1); 62 } 63 bad_array_size()64constexpr size_t bad_array_size() { 65 return std::is_constant_evaluated() ? static_cast<size_t>(-1) : 13; 66 } 67 68 template <class T> require_constexpr(T v)69constexpr T require_constexpr(T v) { 70 if (!std::is_constant_evaluated()) 71 throw "BOOM"; 72 return v; 73 } 74 test_new_expr()75void test_new_expr() { 76 constexpr size_t TooLarge = -1; 77 auto *x = new int[std::is_constant_evaluated() ? 1 : TooLarge]; // expected-error {{array is too large}} 78 auto *x2 = new int[std::is_constant_evaluated() ? TooLarge : 1]; // OK 79 auto *y = new int[1][std::is_constant_evaluated() ? TooLarge : 1]{}; // expected-error {{array is too large}} 80 auto *y2 = new int[1][require_constexpr(42)]; 81 } 82 test_alignas_operand()83void test_alignas_operand() { 84 alignas(std::is_constant_evaluated() ? 8 : 2) char dummy; 85 static_assert(__alignof(dummy) == 8); 86 } 87 test_static_assert_operand()88void test_static_assert_operand() { 89 static_assert(std::is_constant_evaluated(), ""); 90 } 91 test_enumerator()92void test_enumerator() { 93 enum MyEnum { 94 ZERO = 0, 95 ONE = std::is_constant_evaluated() 96 }; 97 static_assert(ONE == 1, ""); 98 } 99 100 struct TestBitfieldWidth { 101 unsigned Bits : std::is_constant_evaluated(); 102 }; 103 104 void test_operand_of_noexcept_fn() noexcept(std::is_constant_evaluated()); 105 static_assert(noexcept(test_operand_of_noexcept_fn()), ""); 106 107 108 namespace test_ref_initialization { 109 int x; 110 int y; 111 int &r = __builtin_is_constant_evaluated() ? x : y; 112 static_assert(&r == &x); 113 114 } // namespace test_ref_initialization 115 116 #if defined(__cpp_conditional_explicit) 117 struct TestConditionalExplicit { TestConditionalExplicitTestConditionalExplicit118 explicit(!__builtin_is_constant_evaluated()) TestConditionalExplicit(int) {} 119 }; 120 TestConditionalExplicit e = 42; 121 #endif 122