blob: 4858d7af9d7e72239554f94ebe77c4fb34d020a0 [file] [log] [blame]
Sebastian Redl10f04a62011-12-22 14:44:04 +00001// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
2
Sebastian Redlcf15cef2011-12-22 18:58:38 +00003struct one { char c[1]; };
4struct two { char c[2]; };
5
Sebastian Redl56a04282012-02-11 23:51:08 +00006namespace std {
7 typedef decltype(sizeof(int)) size_t;
8
9 // libc++'s implementation
10 template <class _E>
11 class initializer_list
12 {
13 const _E* __begin_;
14 size_t __size_;
15
16 initializer_list(const _E* __b, size_t __s)
17 : __begin_(__b),
18 __size_(__s)
19 {}
20
21 public:
22 typedef _E value_type;
23 typedef const _E& reference;
24 typedef const _E& const_reference;
25 typedef size_t size_type;
26
27 typedef const _E* iterator;
28 typedef const _E* const_iterator;
29
30 initializer_list() : __begin_(nullptr), __size_(0) {}
31
32 size_t size() const {return __size_;}
33 const _E* begin() const {return __begin_;}
34 const _E* end() const {return __begin_ + __size_;}
35 };
36}
37
Sebastian Redl10f04a62011-12-22 14:44:04 +000038namespace objects {
39
40 struct X1 { X1(int); };
41 struct X2 { explicit X2(int); }; // expected-note 2 {{candidate constructor}}
42
43 template <int N>
44 struct A {
45 A() { static_assert(N == 0, ""); }
46 A(int, double) { static_assert(N == 1, ""); }
47 };
48
49 template <int N>
Sebastian Redl56a04282012-02-11 23:51:08 +000050 struct F {
51 F() { static_assert(N == 0, ""); }
52 F(int, double) { static_assert(N == 1, ""); }
53 F(std::initializer_list<int>) { static_assert(N == 3, ""); }
54 };
55
56 template <int N>
57 struct D {
58 D(std::initializer_list<int>) { static_assert(N == 0, ""); } // expected-note 1 {{candidate}}
59 D(std::initializer_list<double>) { static_assert(N == 1, ""); } // expected-note 1 {{candidate}}
60 };
61
62 template <int N>
Sebastian Redl10f04a62011-12-22 14:44:04 +000063 struct E {
64 E(int, int) { static_assert(N == 0, ""); }
65 E(X1, int) { static_assert(N == 1, ""); }
66 };
67
68 void overload_resolution() {
69 { A<0> a{}; }
70 { A<0> a = {}; }
71 { A<1> a{1, 1.0}; }
72 { A<1> a = {1, 1.0}; }
73
Sebastian Redl56a04282012-02-11 23:51:08 +000074 { F<0> f{}; }
75 { F<0> f = {}; }
76 // Narrowing conversions don't affect viability. The next two choose
77 // the initializer_list constructor.
78 // FIXME: Emit narrowing conversion errors.
79 { F<3> f{1, 1.0}; } // xpected-error {{narrowing conversion}}
80 { F<3> f = {1, 1.0}; } // xpected-error {{narrowing conversion}}
81 { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }
82 { F<3> f = {1, 2, 3, 4, 5, 6, 7, 8}; }
83 { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }
84 { F<3> f{1, 2}; }
85
86 { D<0> d{1, 2, 3}; }
87 { D<1> d{1.0, 2.0, 3.0}; }
88 { D<-1> d{1, 2.0}; } // expected-error {{ambiguous}}
89
Sebastian Redl10f04a62011-12-22 14:44:04 +000090 { E<0> e{1, 2}; }
91 }
92
93 void explicit_implicit() {
94 { X1 x{0}; }
95 { X1 x = {0}; }
96 { X2 x{0}; }
97 { X2 x = {0}; } // expected-error {{no matching constructor}}
98 }
99
100 struct C {
101 C();
102 C(int, double);
103 C(int, int);
104
105 int operator[](C);
106 };
107
108 C function_call() {
109 void takes_C(C);
110 takes_C({1, 1.0});
111
Sebastian Redlcf15cef2011-12-22 18:58:38 +0000112 C c;
113 c[{1, 1.0}];
Sebastian Redl10f04a62011-12-22 14:44:04 +0000114
115 return {1, 1.0};
116 }
117
118 void inline_init() {
Sebastian Redl62f13c92011-12-22 18:58:29 +0000119 (void) C{1, 1.0};
Sebastian Redl10f04a62011-12-22 14:44:04 +0000120 (void) new C{1, 1.0};
Sebastian Redl56a04282012-02-11 23:51:08 +0000121 (void) A<1>{1, 1.0};
122 (void) new A<1>{1, 1.0};
Sebastian Redl10f04a62011-12-22 14:44:04 +0000123 }
124
Sebastian Redlcf15cef2011-12-22 18:58:38 +0000125 struct B { // expected-note 2 {{candidate constructor}}
126 B(C, int, C); // expected-note {{candidate constructor not viable: cannot convert initializer list argument to 'objects::C'}}
Sebastian Redl10f04a62011-12-22 14:44:04 +0000127 };
128
129 void nested_init() {
Sebastian Redlcf15cef2011-12-22 18:58:38 +0000130 B b1{{1, 1.0}, 2, {3, 4}};
131 B b2{{1, 1.0, 4}, 2, {3, 4}}; // expected-error {{no matching constructor for initialization of 'objects::B'}}
132 }
133
134 void overloaded_call() {
135 one ov1(B); // expected-note {{not viable: cannot convert initializer list}}
136 two ov1(C); // expected-note {{not viable: cannot convert initializer list}}
137
138 static_assert(sizeof(ov1({})) == sizeof(two), "bad overload");
139 static_assert(sizeof(ov1({1, 2})) == sizeof(two), "bad overload");
140 static_assert(sizeof(ov1({{1, 1.0}, 2, {3, 4}})) == sizeof(one), "bad overload");
141
142 ov1({1}); // expected-error {{no matching function}}
Sebastian Redl56a04282012-02-11 23:51:08 +0000143
144 one ov2(int);
145 two ov2(F<3>);
146 static_assert(sizeof(ov2({1})) == sizeof(one), "bad overload"); // list -> int ranks as identity
147 static_assert(sizeof(ov2({1, 2, 3})) == sizeof(two), "bad overload"); // list -> F only viable
Sebastian Redl10f04a62011-12-22 14:44:04 +0000148 }
149}