llvm-project/clang/test/AST/Interp/cxx20.cpp

117 lines
2.9 KiB
C++

// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify %s
// RUN: %clang_cc1 -std=c++20 -verify=ref %s
void test_alignas_operand() {
alignas(8) char dummy;
static_assert(__alignof(dummy) == 8);
}
constexpr int getMinus5() {
int a = 10;
a = -5;
int *p = &a;
return *p;
}
static_assert(getMinus5() == -5, "");
constexpr int assign() {
int m = 10;
int k = 12;
m = (k = 20);
return m;
}
static_assert(assign() == 20, "");
constexpr int pointerAssign() {
int m = 10;
int *p = &m;
*p = 12; // modifies m
return m;
}
static_assert(pointerAssign() == 12, "");
constexpr int pointerDeref() {
int m = 12;
int *p = &m;
return *p;
}
static_assert(pointerDeref() == 12, "");
constexpr int pointerAssign2() {
int m = 10;
int *p = &m;
int **pp = &p;
**pp = 12;
int v = **pp;
return v;
}
static_assert(pointerAssign2() == 12, "");
constexpr int unInitLocal() {
int a;
return a; // ref-note{{read of uninitialized object}}
}
static_assert(unInitLocal() == 0, ""); // expected-error {{not an integral constant expression}} \
// ref-error {{not an integral constant expression}} \
// ref-note {{in call to 'unInitLocal()'}}
/// TODO: The example above is correctly rejected by the new constexpr
/// interpreter, but for the wrong reasons. We don't reject it because
/// it is an uninitialized read, we reject it simply because
/// the local variable does not have an initializer.
///
/// The code below should be accepted but is also being rejected
/// right now.
#if 0
constexpr int initializedLocal() {
int a;
int b;
a = 20;
return a;
}
static_assert(initializedLocal() == 20);
/// Similar here, but the uninitialized local is passed as a function parameter.
constexpr int inc(int a) { return a + 1; }
constexpr int f() {
int i;
return inc(i);
}
static_assert(f());
#endif
/// Distinct literals have disctinct addresses.
/// see https://github.com/llvm/llvm-project/issues/58754
constexpr auto foo(const char *p) { return p; }
constexpr auto p1 = "test1";
constexpr auto p2 = "test2";
constexpr bool b1 = foo(p1) == foo(p1);
static_assert(b1);
constexpr bool b2 = foo(p1) == foo(p2); // ref-error {{must be initialized by a constant expression}} \
// ref-note {{declared here}}
static_assert(!b2); // ref-error {{not an integral constant expression}} \
// ref-note {{not a constant expression}}
constexpr auto name1() { return "name1"; }
constexpr auto name2() { return "name2"; }
constexpr auto b3 = name1() == name1();
static_assert(b3);
constexpr auto b4 = name1() == name2(); // ref-error {{must be initialized by a constant expression}} \
// ref-note {{declared here}}
static_assert(!b4); // ref-error {{not an integral constant expression}} \
// ref-note {{not a constant expression}}