diff options
Diffstat (limited to 'test/SemaCXX/builtin-is-constant-evaluated.cpp')
-rw-r--r-- | test/SemaCXX/builtin-is-constant-evaluated.cpp | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/test/SemaCXX/builtin-is-constant-evaluated.cpp b/test/SemaCXX/builtin-is-constant-evaluated.cpp new file mode 100644 index 0000000000..47b54d6ac3 --- /dev/null +++ b/test/SemaCXX/builtin-is-constant-evaluated.cpp @@ -0,0 +1,121 @@ +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu + +using size_t = decltype(sizeof(int)); + +namespace std { +inline constexpr bool is_constant_evaluated() noexcept { + return __builtin_is_constant_evaluated(); +} +} // namespace std + +extern int dummy; // expected-note 1+ {{declared here}} + +static_assert(__builtin_is_constant_evaluated()); +static_assert(noexcept(__builtin_is_constant_evaluated())); + +constexpr bool b = __builtin_is_constant_evaluated(); +static_assert(b); + +const int n = __builtin_is_constant_evaluated() ? 4 : dummy; +static_assert(n == 4); +constexpr int cn = __builtin_is_constant_evaluated() ? 11 : dummy; +static_assert(cn == 11); +// expected-error@+1 {{'bn' must be initialized by a constant expression}} +constexpr int bn = __builtin_is_constant_evaluated() ? dummy : 42; // expected-note {{non-const variable 'dummy' is not allowed}} + +const int n2 = __builtin_is_constant_evaluated() ? dummy : 42; // expected-note {{declared here}} +static_assert(n2 == 42); // expected-error {{static_assert expression is not an integral constant}} +// expected-note@-1 {{initializer of 'n2' is not a constant expression}} + +template <bool V, bool Default = std::is_constant_evaluated()> +struct Templ { static_assert(V); static_assert(Default); }; +Templ<__builtin_is_constant_evaluated()> x; // type X<true> + +template <class T> +void test_if_constexpr() { + if constexpr (__builtin_is_constant_evaluated()) { + static_assert(__is_same(T, int)); + } else { + using Test = typename T::DOES_NOT_EXIST; + } +} +template void test_if_constexpr<int>(); + +void test_array_decl() { + char x[__builtin_is_constant_evaluated() + std::is_constant_evaluated()]; + static_assert(sizeof(x) == 2, ""); +} + +void test_case_stmt(int x) { + switch (x) { + case 0: // OK + case __builtin_is_constant_evaluated(): // expected-note {{previous case}} + case std::is_constant_evaluated() + __builtin_is_constant_evaluated(): // expected-note {{previous case}} + case 1: // expected-error {{duplicate case value '1'}} + case 2: // expected-error {{duplicate case value '2'}} + break; + } +} + +constexpr size_t good_array_size() { + return std::is_constant_evaluated() ? 42 : static_cast<size_t>(-1); +} + +constexpr size_t bad_array_size() { + return std::is_constant_evaluated() ? static_cast<size_t>(-1) : 13; +} + +template <class T> +constexpr T require_constexpr(T v) { + if (!std::is_constant_evaluated()) + throw "BOOM"; + return v; +} + +void test_new_expr() { + constexpr size_t TooLarge = -1; + auto *x = new int[std::is_constant_evaluated() ? 1 : TooLarge]; // expected-error {{array is too large}} + auto *x2 = new int[std::is_constant_evaluated() ? TooLarge : 1]; // OK + auto *y = new int[1][std::is_constant_evaluated() ? TooLarge : 1]{}; // expected-error {{array is too large}} + auto *y2 = new int[1][require_constexpr(42)]; +} + +void test_alignas_operand() { + alignas(std::is_constant_evaluated() ? 8 : 2) char dummy; + static_assert(__alignof(dummy) == 8); +} + +void test_static_assert_operand() { + static_assert(std::is_constant_evaluated(), ""); +} + +void test_enumerator() { + enum MyEnum { + ZERO = 0, + ONE = std::is_constant_evaluated() + }; + static_assert(ONE == 1, ""); +} + +struct TestBitfieldWidth { + unsigned Bits : std::is_constant_evaluated(); +}; + +void test_operand_of_noexcept_fn() noexcept(std::is_constant_evaluated()); +static_assert(noexcept(test_operand_of_noexcept_fn()), ""); + + +namespace test_ref_initialization { +int x; +int y; +int &r = __builtin_is_constant_evaluated() ? x : y; +static_assert(&r == &x); + +} // namespace test_ref_initialization + +#if defined(__cpp_conditional_explicit) +struct TestConditionalExplicit { + explicit(__builtin_is_constant_evaluated()) TestConditionalExplicit(int) {} +}; +TestConditionalExplicit e = 42; +#endif |