1 // RUN: %clang_cc1 -std=c++20 -verify -fconstexpr-steps=1024 -Wvla %s
4 using size_t = decltype(sizeof(0));
7 void *operator new(std::size_t, void *p
) { return p
; }
10 template<typename T
> struct allocator
{
11 constexpr T
*allocate(size_t N
) {
12 return (T
*)operator new(sizeof(T
) * N
); // #alloc
14 constexpr void deallocate(void *p
) {
18 template<typename T
, typename
...Args
>
19 constexpr void construct_at(void *p
, Args
&&...args
) { // #construct
20 new (p
) T((Args
&&)args
...);
28 constexpr S(unsigned long long N
)
30 data
= alloc
.allocate(N
); // #call
31 for(std::size_t i
= 0; i
< N
; i
++)
32 std::construct_at
<T
>(data
+ i
, i
); // #construct_call
34 constexpr T
operator[](std::size_t i
) const {
39 alloc
.deallocate(data
);
41 std::allocator
<T
> alloc
;
45 // Only run these tests on 64 bits platforms
47 constexpr 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({{.*}})'}}
52 // Check that we do not try to fold very large arrays
53 std::size_t s2
= S
<std::size_t>(~0UL)[42];
54 std::size_t s3
= S
<std::size_t>(~0ULL)[42];
56 // We can allocate and initialize a small array
57 constexpr std::size_t ssmall
= S
<std::size_t>(100)[42];
59 // We can allocate this array but we hikt the number of steps
60 constexpr 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}}
67 constexpr 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}}
73 // Check we do not perform constant initialization in the presence
74 // of very large arrays (this used to crash)
77 constexpr 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}}
82 int a
= stack_array
<~0U>();
83 int c
= stack_array
<1024>();
84 int d
= stack_array
<1025>();
85 constexpr int e
= stack_array
<1024>();
86 constexpr int f
= stack_array
<1025>(); // expected-error {{constexpr variable 'f' must be initialized by a constant expression}} \
87 // expected-note {{in call}}
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>()'}}
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>()'}}