74 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -verify=ref,both -fconstexpr-steps=1024 -Wvla %s2// RUN: %clang_cc1 -std=c++20 -verify=both,both -fconstexpr-steps=1024 -Wvla %s -fexperimental-new-constant-interpreter3 4 5 6 7namespace std {8 using size_t = decltype(sizeof(0));9}10 11void *operator new(std::size_t, void *p) { return p; }12 13namespace std {14 template<typename T> struct allocator {15 constexpr T *allocate(size_t N) {16 return (T*)operator new(sizeof(T) * N); // #alloc17 }18 constexpr void deallocate(void *p) {19 operator delete(p);20 }21 };22 template<typename T, typename ...Args>23 constexpr void construct_at(void *p, Args &&...args) { // #construct24 new (p) T((Args&&)args...);25 }26}27 28template <typename T>29struct S {30 constexpr S(unsigned long long N)31 : data(nullptr){32 data = alloc.allocate(N); // #call33 for(std::size_t i = 0; i < N; i ++)34 std::construct_at<T>(data + i, i); // #construct_call35 }36 constexpr T operator[](std::size_t i) const {37 return data[i];38 }39 40 constexpr ~S() {41 alloc.deallocate(data);42 }43 std::allocator<T> alloc;44 T* data;45};46 47#if __LP64__48constexpr std::size_t s = S<std::size_t>(~0UL)[42]; // both-error {{constexpr variable 's' must be initialized by a constant expression}} \49 // both-note-re@#call {{in call to 'this->alloc.allocate({{.*}})'}} \50 // both-note-re@#alloc {{cannot allocate array; evaluated array bound {{.*}} is too large}} \51 // both-note-re {{in call to 'S({{.*}})'}}52#endif53 54constexpr std::size_t ssmall = S<std::size_t>(100)[42];55 56constexpr std::size_t s5 = S<std::size_t>(1025)[42]; // both-error {{constexpr variable 's5' must be initialized by a constant expression}} \57 // both-note@#alloc {{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024); use '-fconstexpr-steps' to increase this limit}} \58 // both-note@#call {{in call to 'this->alloc.allocate(1025)'}} \59 // both-note {{in call}}60 61 62 63template <auto N>64constexpr int stack_array() {65 [[maybe_unused]] char BIG[N] = {1}; // both-note {{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024)}}66 return BIG[N-1];67}68 69int c = stack_array<1024>();70int d = stack_array<1025>();71constexpr int e = stack_array<1024>();72constexpr int f = stack_array<1025>(); // both-error {{constexpr variable 'f' must be initialized by a constant expression}} \73 // both-note {{in call}}74