1d6d60707STimm Baeder // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -fms-extensions -std=c++20 -verify=expected,both %s 2d6d60707STimm Baeder // RUN: %clang_cc1 -std=c++20 -fms-extensions -verify=ref,both %s 3d6d60707STimm Baeder 4d6d60707STimm Baeder namespace std { 5d6d60707STimm Baeder typedef decltype(sizeof(int)) size_t; 6d6d60707STimm Baeder template <class _E> 7d6d60707STimm Baeder class initializer_list 8d6d60707STimm Baeder { 9d6d60707STimm Baeder const _E* __begin_; 10d6d60707STimm Baeder size_t __size_; 11d6d60707STimm Baeder 12d6d60707STimm Baeder initializer_list(const _E* __b, size_t __s) 13d6d60707STimm Baeder : __begin_(__b), 14d6d60707STimm Baeder __size_(__s) 15d6d60707STimm Baeder {} 16d6d60707STimm Baeder 17d6d60707STimm Baeder public: 18d6d60707STimm Baeder typedef _E value_type; 19d6d60707STimm Baeder typedef const _E& reference; 20d6d60707STimm Baeder typedef const _E& const_reference; 21d6d60707STimm Baeder typedef size_t size_type; 22d6d60707STimm Baeder 23d6d60707STimm Baeder typedef const _E* iterator; 24d6d60707STimm Baeder typedef const _E* const_iterator; 25d6d60707STimm Baeder 26d6d60707STimm Baeder constexpr initializer_list() : __begin_(nullptr), __size_(0) {} 27d6d60707STimm Baeder 28d6d60707STimm Baeder constexpr size_t size() const {return __size_;} 29d6d60707STimm Baeder constexpr const _E* begin() const {return __begin_;} 30d6d60707STimm Baeder constexpr const _E* end() const {return __begin_ + __size_;} 31d6d60707STimm Baeder }; 32d6d60707STimm Baeder } 33d6d60707STimm Baeder 34d6d60707STimm Baeder class Thing { 35d6d60707STimm Baeder public: 36d6d60707STimm Baeder int m = 12; 37d6d60707STimm Baeder constexpr Thing(int m) : m(m) {} 38d6d60707STimm Baeder constexpr bool operator==(const Thing& that) const { 39d6d60707STimm Baeder return this->m == that.m; 40d6d60707STimm Baeder } 41d6d60707STimm Baeder }; 42d6d60707STimm Baeder 43d6d60707STimm Baeder constexpr bool is_contained(std::initializer_list<Thing> Set, const Thing &Element) { 44d6d60707STimm Baeder return (*Set.begin() == Element); 45d6d60707STimm Baeder } 46d6d60707STimm Baeder 47d6d60707STimm Baeder constexpr int foo() { 48d6d60707STimm Baeder const Thing a{12}; 49d6d60707STimm Baeder const Thing b{14}; 50d6d60707STimm Baeder return is_contained({a}, b); 51d6d60707STimm Baeder } 52d6d60707STimm Baeder 53d6d60707STimm Baeder static_assert(foo() == 0); 54*35f7cfb2STimm Baeder 55*35f7cfb2STimm Baeder 56*35f7cfb2STimm Baeder namespace rdar13395022 { 57*35f7cfb2STimm Baeder struct MoveOnly { // both-note {{candidate}} 58*35f7cfb2STimm Baeder MoveOnly(MoveOnly&&); // both-note 2{{copy constructor is implicitly deleted because}} both-note {{candidate}} 59*35f7cfb2STimm Baeder }; 60*35f7cfb2STimm Baeder 61*35f7cfb2STimm Baeder void test(MoveOnly mo) { 62*35f7cfb2STimm Baeder auto &&list1 = {mo}; // both-error {{call to implicitly-deleted copy constructor}} both-note {{in initialization of temporary of type 'std::initializer_list}} 63*35f7cfb2STimm Baeder MoveOnly (&&list2)[1] = {mo}; // both-error {{call to implicitly-deleted copy constructor}} both-note {{in initialization of temporary of type 'MoveOnly[1]'}} 64*35f7cfb2STimm Baeder std::initializer_list<MoveOnly> &&list3 = {}; 65*35f7cfb2STimm Baeder MoveOnly (&&list4)[1] = {}; // both-error {{no matching constructor}} 66*35f7cfb2STimm Baeder // both-note@-1 {{in implicit initialization of array element 0 with omitted initializer}} 67*35f7cfb2STimm Baeder // both-note@-2 {{in initialization of temporary of type 'MoveOnly[1]' created to list-initialize this reference}} 68*35f7cfb2STimm Baeder } 69*35f7cfb2STimm Baeder } 70*35f7cfb2STimm Baeder 71*35f7cfb2STimm Baeder 72