// RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both %s // RUN: %clang_cc1 -std=c++20 -verify=ref,both %s using intptr_t = __INTPTR_TYPE__; static_assert(__builtin_constant_p(12), ""); static_assert(__builtin_constant_p(1.0), ""); constexpr int I = 100; static_assert(__builtin_constant_p(I), ""); static_assert(__builtin_constant_p(I + 10), ""); static_assert(__builtin_constant_p(I + 10.0), ""); static_assert(__builtin_constant_p(nullptr), ""); static_assert(__builtin_constant_p(&I), ""); // both-error {{failed due to requirement}} static_assert(__builtin_constant_p((void)I), ""); // both-error {{failed due to requirement}} extern int z; constexpr int foo(int &a) { return __builtin_constant_p(a); } static_assert(!foo(z)); static_assert(__builtin_constant_p(__builtin_constant_p(1))); constexpr bool nested(int& a) { return __builtin_constant_p(__builtin_constant_p(a)); } static_assert(nested(z)); constexpr bool Local() { int z = 10; return __builtin_constant_p(z); } static_assert(Local()); constexpr bool Local2() { int z = 10; return __builtin_constant_p(&z); } static_assert(!Local2()); constexpr bool Parameter(int a) { return __builtin_constant_p(a); } static_assert(Parameter(10)); constexpr bool InvalidLocal() { int *z; { int b = 10; z = &b; } return __builtin_constant_p(z); } static_assert(!InvalidLocal()); template constexpr bool bcp(T t) { return __builtin_constant_p(t); } constexpr intptr_t ptr_to_int(const void *p) { return __builtin_constant_p(1) ? (intptr_t)p : (intptr_t)p; } static_assert(bcp(ptr_to_int("foo"))); constexpr bool AndFold(const int &a, const int &b) { return __builtin_constant_p(a && b); } static_assert(AndFold(10, 20)); static_assert(!AndFold(z, 10)); static_assert(!AndFold(10, z)); struct F { int a; }; constexpr F f{12}; static_assert(__builtin_constant_p(f.a)); constexpr bool Member() { F f; return __builtin_constant_p(f.a); } static_assert(!Member()); constexpr bool Discard() { (void)__builtin_constant_p(10); return true; } static_assert(Discard()); static_assert(__builtin_constant_p((int*)123)); constexpr void func() {} static_assert(!__builtin_constant_p(func)); /// This is from SemaCXX/builtin-constant-p and GCC agrees with the bytecode interpreter. constexpr int mutate1() { int n = 1; int m = __builtin_constant_p(++n); return n * 10 + m; } static_assert(mutate1() == 21); // ref-error {{static assertion failed}} \ // ref-note {{evaluates to '10 == 21'}} /// Similar for this. GCC agrees with the bytecode interpreter. constexpr int mutate_param(bool mutate, int ¶m) { mutate = mutate; // Mutation of internal state is OK if (mutate) ++param; return param; } constexpr int mutate6(bool mutate) { int n = 1; int m = __builtin_constant_p(mutate_param(mutate, n)); return n * 10 + m; } static_assert(mutate6(false) == 11); static_assert(mutate6(true) == 21); // ref-error {{static assertion failed}} \ // ref-note {{evaluates to '10 == 21'}}