xref: /llvm-project/clang/test/SemaCXX/overload-ary-bind.cpp (revision bb3f5f5d788dd9375ab260f77612fab4a707a1ac)
1*bb3f5f5dSNathan Sidwell // RUN: %clang_cc1 -std=c++20 -verify %s
2*bb3f5f5dSNathan Sidwell // RUN: %clang_cc1 -std=c++17 -verify %s
3*bb3f5f5dSNathan Sidwell 
4*bb3f5f5dSNathan Sidwell namespace One {
5*bb3f5f5dSNathan Sidwell char (&b(int(&&)[1]))[1]; // #1 expected-note{{too many initializers}}
6*bb3f5f5dSNathan Sidwell char (&b(int(&&)[2]))[2]; // #2 expected-note{{too many initializers}}
7*bb3f5f5dSNathan Sidwell 
f()8*bb3f5f5dSNathan Sidwell void f() {
9*bb3f5f5dSNathan Sidwell   static_assert(sizeof(b({1})) == 1);    // #1
10*bb3f5f5dSNathan Sidwell   static_assert(sizeof(b({1, 2})) == 2); // #2
11*bb3f5f5dSNathan Sidwell 
12*bb3f5f5dSNathan Sidwell   b({1, 2, 3}); // expected-error{{no matching function}}
13*bb3f5f5dSNathan Sidwell }
14*bb3f5f5dSNathan Sidwell } // namespace One
15*bb3f5f5dSNathan Sidwell 
16*bb3f5f5dSNathan Sidwell namespace Two {
17*bb3f5f5dSNathan Sidwell struct Bob {
18*bb3f5f5dSNathan Sidwell   Bob(int = 1);
19*bb3f5f5dSNathan Sidwell };
20*bb3f5f5dSNathan Sidwell 
21*bb3f5f5dSNathan Sidwell char (&b(Bob(&&)[1]))[1]; // #1
22*bb3f5f5dSNathan Sidwell char (&b(Bob(&&)[2]))[2]; // #2
23*bb3f5f5dSNathan Sidwell 
f()24*bb3f5f5dSNathan Sidwell void f() {
25*bb3f5f5dSNathan Sidwell   static_assert(sizeof(b({})) == 1);         // #1
26*bb3f5f5dSNathan Sidwell   static_assert(sizeof(b({Bob()})) == 1);    // #1
27*bb3f5f5dSNathan Sidwell   static_assert(sizeof(b({2, Bob()})) == 2); // #2
28*bb3f5f5dSNathan Sidwell }
29*bb3f5f5dSNathan Sidwell } // namespace Two
30*bb3f5f5dSNathan Sidwell 
31*bb3f5f5dSNathan Sidwell namespace Three {
32*bb3f5f5dSNathan Sidwell struct Kevin {
33*bb3f5f5dSNathan Sidwell   Kevin(int);
34*bb3f5f5dSNathan Sidwell };
35*bb3f5f5dSNathan Sidwell 
36*bb3f5f5dSNathan Sidwell char (&b(Kevin(&&)[2]))[2]; // #2 expected-note{{too few initializers}}
37*bb3f5f5dSNathan Sidwell 
f()38*bb3f5f5dSNathan Sidwell void f() {
39*bb3f5f5dSNathan Sidwell   b({2}); // #1 expected-error{{no matching function}}
40*bb3f5f5dSNathan Sidwell }
41*bb3f5f5dSNathan Sidwell } // namespace Three
42*bb3f5f5dSNathan Sidwell 
43*bb3f5f5dSNathan Sidwell namespace Four {
44*bb3f5f5dSNathan Sidwell char (&b(int(&&)[1], float))[1];  // #1 expected-note{{candidate}}
45*bb3f5f5dSNathan Sidwell char (&b(int(&&)[1], double))[2]; // #2 expected-note{{candidate}}
46*bb3f5f5dSNathan Sidwell 
47*bb3f5f5dSNathan Sidwell char (&c(float, int(&&)[1]))[1];  // #1 expected-note{{candidate}}
48*bb3f5f5dSNathan Sidwell char (&c(double, int(&&)[1]))[2]; // #2 expected-note{{candidate}}
49*bb3f5f5dSNathan Sidwell 
f()50*bb3f5f5dSNathan Sidwell void f() {
51*bb3f5f5dSNathan Sidwell   b({1}, 0); // expected-error{{is ambiguous}}
52*bb3f5f5dSNathan Sidwell   c(0, {1}); // expected-error{{is ambiguous}}
53*bb3f5f5dSNathan Sidwell }
54*bb3f5f5dSNathan Sidwell } // namespace Four
55*bb3f5f5dSNathan Sidwell 
56*bb3f5f5dSNathan Sidwell typedef decltype(sizeof(char)) size_t;
57*bb3f5f5dSNathan Sidwell namespace std {
58*bb3f5f5dSNathan Sidwell // sufficient initializer list
59*bb3f5f5dSNathan Sidwell template <class _E>
60*bb3f5f5dSNathan Sidwell class initializer_list {
61*bb3f5f5dSNathan Sidwell   const _E *__begin_;
62*bb3f5f5dSNathan Sidwell   size_t __size_;
63*bb3f5f5dSNathan Sidwell 
initializer_list(const _E * __b,size_t __s)64*bb3f5f5dSNathan Sidwell   constexpr initializer_list(const _E *__b, size_t __s)
65*bb3f5f5dSNathan Sidwell       : __begin_(__b),
66*bb3f5f5dSNathan Sidwell         __size_(__s) {}
67*bb3f5f5dSNathan Sidwell 
68*bb3f5f5dSNathan Sidwell public:
69*bb3f5f5dSNathan Sidwell   typedef _E value_type;
70*bb3f5f5dSNathan Sidwell   typedef const _E &reference;
71*bb3f5f5dSNathan Sidwell   typedef const _E &const_reference;
72*bb3f5f5dSNathan Sidwell   typedef size_t size_type;
73*bb3f5f5dSNathan Sidwell 
74*bb3f5f5dSNathan Sidwell   typedef const _E *iterator;
75*bb3f5f5dSNathan Sidwell   typedef const _E *const_iterator;
76*bb3f5f5dSNathan Sidwell 
initializer_list()77*bb3f5f5dSNathan Sidwell   constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
78*bb3f5f5dSNathan Sidwell 
size() const79*bb3f5f5dSNathan Sidwell   constexpr size_t size() const { return __size_; }
begin() const80*bb3f5f5dSNathan Sidwell   constexpr const _E *begin() const { return __begin_; }
end() const81*bb3f5f5dSNathan Sidwell   constexpr const _E *end() const { return __begin_ + __size_; }
82*bb3f5f5dSNathan Sidwell };
83*bb3f5f5dSNathan Sidwell } // namespace std
84*bb3f5f5dSNathan Sidwell 
85*bb3f5f5dSNathan Sidwell namespace Five {
86*bb3f5f5dSNathan Sidwell struct ugly {
87*bb3f5f5dSNathan Sidwell   ugly(char *);
88*bb3f5f5dSNathan Sidwell   ugly(int);
89*bb3f5f5dSNathan Sidwell };
90*bb3f5f5dSNathan Sidwell char (&f(std::initializer_list<char *>))[1]; // #1
91*bb3f5f5dSNathan Sidwell char (&f(std::initializer_list<ugly>))[2];   // #2
g()92*bb3f5f5dSNathan Sidwell void g() {
93*bb3f5f5dSNathan Sidwell   // Pick #2 as #1 not viable (3->char * fails).
94*bb3f5f5dSNathan Sidwell   static_assert(sizeof(f({"hello", 3})) == 2); // expected-warning{{not allow}}
95*bb3f5f5dSNathan Sidwell }
96*bb3f5f5dSNathan Sidwell 
97*bb3f5f5dSNathan Sidwell } // namespace Five
98