1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -pedantic-errors |
2 | |
3 | struct one { char c[1]; }; |
4 | struct two { char c[2]; }; |
5 | |
6 | namespace 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 | |
38 | namespace integral { |
39 | |
40 | void initialization() { |
41 | { const int a{}; static_assert(a == 0, ""); } |
42 | { const int a = {}; static_assert(a == 0, ""); } |
43 | { const int a{1}; static_assert(a == 1, ""); } |
44 | { const int a = {1}; static_assert(a == 1, ""); } |
45 | { const int a{1, 2}; } // expected-error {{excess elements}} |
46 | { const int a = {1, 2}; } // expected-error {{excess elements}} |
47 | // FIXME: Redundant warnings. |
48 | { const short a{100000}; } // expected-error {{cannot be narrowed}} expected-note {{insert an explicit cast}} expected-warning {{changes value}} |
49 | { const short a = {100000}; } // expected-error {{cannot be narrowed}} expected-note {{insert an explicit cast}} expected-warning {{changes value}} |
50 | { if (const int a{1}) static_assert(a == 1, ""); } |
51 | { if (const int a = {1}) static_assert(a == 1, ""); } |
52 | } |
53 | |
54 | int direct_usage() { |
55 | int ar[10]; |
56 | (void) ar[{1}]; // expected-error {{array subscript is not an integer}} |
57 | |
58 | return {1}; // expected-warning {{braces around scalar init}} |
59 | } |
60 | |
61 | void inline_init() { |
62 | auto v = int{1}; |
63 | (void) new int{1}; |
64 | } |
65 | |
66 | struct A { |
67 | int i; |
68 | A() : i{1} {} |
69 | }; |
70 | |
71 | void function_call() { |
72 | void takes_int(int); |
73 | takes_int({1}); // expected-warning {{braces around scalar init}} |
74 | } |
75 | |
76 | void overloaded_call() { |
77 | one overloaded(int); |
78 | two overloaded(double); |
79 | |
80 | static_assert(sizeof(overloaded({0})) == sizeof(one), "bad overload"); // expected-warning {{braces around scalar init}} |
81 | static_assert(sizeof(overloaded({0.0})) == sizeof(two), "bad overload"); // expected-warning {{braces around scalar init}} |
82 | |
83 | void ambiguous(int, double); // expected-note {{candidate}} |
84 | void ambiguous(double, int); // expected-note {{candidate}} |
85 | ambiguous({0}, {0}); // expected-error {{ambiguous}} |
86 | |
87 | void emptylist(int); |
88 | void emptylist(int, int, int); |
89 | emptylist({}); |
90 | emptylist({}, {}, {}); |
91 | } |
92 | |
93 | void edge_cases() { |
94 | int a({0}); // expected-error {{cannot initialize non-class type 'int' with a parenthesized initializer list}} |
95 | (void) int({0}); // expected-error {{cannot initialize non-class type 'int' with a parenthesized initializer list}} |
96 | new int({0}); // expected-error {{cannot initialize non-class type 'int' with a parenthesized initializer list}} |
97 | |
98 | int *b({0}); // expected-error {{cannot initialize non-class type 'int *' with a parenthesized initializer list}} |
99 | typedef int *intptr; |
100 | int *c = intptr({0}); // expected-error {{cannot initialize non-class type 'intptr' (aka 'int *') with a parenthesized initializer list}} |
101 | } |
102 | |
103 | template<typename T> void dependent_edge_cases() { |
104 | T a({0}); |
105 | (void) T({0}); |
106 | new T({0}); |
107 | |
108 | T *b({0}); |
109 | typedef T *tptr; |
110 | T *c = tptr({0}); |
111 | } |
112 | |
113 | void default_argument(int i = {}) { |
114 | } |
115 | struct DefaultArgument { |
116 | void default_argument(int i = {}) { |
117 | } |
118 | }; |
119 | } |
120 | |
121 | namespace PR12118 { |
122 | void test() { |
123 | one f(std::initializer_list<int>); |
124 | two f(int); |
125 | |
126 | // to initializer_list is preferred |
127 | static_assert(sizeof(f({0})) == sizeof(one), "bad overload"); |
128 | } |
129 | } |
130 | |
131 | namespace excess_braces_sfinae { |
132 | using valid = int&; |
133 | using invalid = float&; |
134 | |
135 | template<typename T> valid braces1(decltype(T{0})*); |
136 | template<typename T> invalid braces1(...); |
137 | |
138 | template<typename T> valid braces2(decltype(T{{0}})*); |
139 | template<typename T> invalid braces2(...); |
140 | |
141 | template<typename T> valid braces3(decltype(T{{{0}}})*); |
142 | template<typename T> invalid braces3(...); |
143 | |
144 | valid a = braces1<int>(0); |
145 | invalid b = braces2<int>(0); |
146 | invalid c = braces3<int>(0); |
147 | |
148 | struct X { int n; }; |
149 | valid d = braces1<X>(0); |
150 | valid e = braces2<X>(0); |
151 | invalid f = braces3<X>(0); |
152 | } |
153 | |