brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · 8bcb4d4 Raw
99 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -verify -fconstexpr-steps=1024 -Wvla %s2 3namespace std {4  using size_t = decltype(sizeof(0));5}6 7void *operator new(std::size_t, void *p) { return p; }8 9namespace std {10  template<typename T> struct allocator {11    constexpr T *allocate(size_t N) {12      return (T*)operator new(sizeof(T) * N); // #alloc13    }14    constexpr void deallocate(void *p) {15      operator delete(p);16    }17  };18  template<typename T, typename ...Args>19  constexpr void construct_at(void *p, Args &&...args) { // #construct20    new (p) T((Args&&)args...);21  }22}23 24namespace GH63562 {25 26template <typename T>27struct S {28    constexpr S(unsigned long long N)29    : data(nullptr){30        data = alloc.allocate(N);  // #call31        for(std::size_t i = 0; i < N; i ++)32            std::construct_at<T>(data + i, i); // #construct_call33    }34    constexpr T operator[](std::size_t i) const {35      return data[i];36    }37 38    constexpr ~S() {39        alloc.deallocate(data);40    }41    std::allocator<T> alloc;42    T* data;43};44 45// Only run these tests on 64 bits platforms46#if __LP64__47constexpr std::size_t s = S<std::size_t>(~0UL)[42]; // expected-error {{constexpr variable 's' must be initialized by a constant expression}} \48                                           // expected-note-re@#call {{in call to 'this->alloc.allocate({{.*}})'}} \49                                           // expected-note-re@#alloc {{cannot allocate array; evaluated array bound {{.*}} is too large}} \50                                           // expected-note-re {{in call to 'S({{.*}})'}}51#endif52// Check that we do not try to fold very large arrays53std::size_t s2 = S<std::size_t>(~0UL)[42];54std::size_t s3 = S<std::size_t>(~0ULL)[42];55 56// We can allocate and initialize a small array57constexpr std::size_t ssmall = S<std::size_t>(100)[42];58 59// We can allocate this array but we hikt the number of steps60constexpr std::size_t s4 = S<std::size_t>(1024)[42]; // expected-error {{constexpr variable 's4' must be initialized by a constant expression}} \61                                   // expected-note@#construct {{constexpr evaluation hit maximum step limit; possible infinite loop?}} \62                                   // expected-note@#construct_call {{in call}} \63                                   // expected-note {{in call}}64 65 66 67constexpr std::size_t s5 = S<std::size_t>(1025)[42]; // expected-error{{constexpr variable 's5' must be initialized by a constant expression}} \68                                   // expected-note@#alloc {{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024); use '-fconstexpr-steps' to increase this limit}} \69                                   // expected-note@#call {{in call to 'this->alloc.allocate(1025)'}} \70                                   // expected-note {{in call}}71 72 73// Check we do not perform constant initialization in the presence74// of very large arrays (this used to crash)75 76template <auto N>77constexpr int stack_array() {78    [[maybe_unused]] char BIG[N] = {1};  // expected-note  3{{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024); use '-fconstexpr-steps' to increase this limit}}79    return BIG[N-1];80}81 82int a = stack_array<~0U>();83int c = stack_array<1024>();84int d = stack_array<1025>();85constexpr int e = stack_array<1024>();86constexpr int f = stack_array<1025>(); // expected-error {{constexpr variable 'f' must be initialized by a constant expression}} \87                                       //  expected-note {{in call}}88void ohno() {89  int bar[stack_array<1024>()];90  int foo[stack_array<1025>()]; // expected-warning {{variable length arrays in C++ are a Clang extension}} \91                                // expected-note {{in call to 'stack_array<1025>()'}}92 93  constexpr int foo[stack_array<1025>()]; // expected-warning {{variable length arrays in C++ are a Clang extension}} \94                                          // expected-error {{constexpr variable cannot have non-literal type 'const int[stack_array<1025>()]'}} \95                                          // expected-note {{in call to 'stack_array<1025>()'}}96}97 98}99