mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 19:16:05 +00:00

This is similar to what the current interpreter is doing - the FoldConstant RAII object surrounds the entire HandleConditionalOperator call, which means the condition and both TrueExpr or FalseExpr.
124 lines
3.0 KiB
C++
124 lines
3.0 KiB
C++
// 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<typename T> 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'}}
|