1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++1y -triple x86_64-linux-gnu %s |
2 | |
3 | // If there is a preceding declaration of the entity *in the same scope* in |
4 | // which the bound was specified, an omitted array bound is taken to be the |
5 | // same as in that earlier declaration |
6 | |
7 | // rdar://13535367 |
8 | namespace test0 { |
9 | extern "C" int array[]; |
10 | void declare() { extern int array[100]; } |
11 | int value1 = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} |
12 | extern "C" int array[]; |
13 | int value2 = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} |
14 | } |
15 | |
16 | namespace test1 { |
17 | extern "C" int array[]; |
18 | void test() { |
19 | { extern int array[100]; } |
20 | extern int array[]; |
21 | int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} |
22 | } |
23 | } |
24 | |
25 | namespace test2 { |
26 | void declare() { extern int array[100]; } |
27 | extern int array[]; |
28 | int value = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} |
29 | } |
30 | |
31 | namespace test3 { |
32 | void test() { |
33 | { extern int array[100]; } |
34 | extern int array[]; |
35 | int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} |
36 | } |
37 | } |
38 | |
39 | namespace test4 { |
40 | extern int array[]; |
41 | void test() { |
42 | extern int array[100]; |
43 | int x = sizeof(array); |
44 | } |
45 | int y = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} |
46 | } |
47 | |
48 | namespace test5 { |
49 | void test() { |
50 | extern int array[100]; |
51 | extern int array[]; |
52 | int x = sizeof(array); |
53 | } |
54 | } |
55 | |
56 | namespace test6 { |
57 | void test() { |
58 | extern int array[100]; |
59 | { |
60 | extern int array[]; |
61 | int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} |
62 | } |
63 | int y = sizeof(array); |
64 | extern int array[]; |
65 | int z = sizeof(array); |
66 | } |
67 | } |
68 | |
69 | namespace test7 { |
70 | extern int array[100]; |
71 | void test() { |
72 | extern int array[]; |
73 | int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} |
74 | } |
75 | int y = sizeof(array); |
76 | extern int array[]; |
77 | int z = sizeof(array); |
78 | } |
79 | |
80 | namespace test8 { |
81 | extern int array[]; |
82 | void test() { |
83 | extern int array[100]; |
84 | int x = sizeof(array); |
85 | } |
86 | int y = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} |
87 | extern int array[]; |
88 | int z = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} |
89 | } |
90 | |
91 | namespace dependent { |
92 | template<typename T> void f() { |
93 | extern int arr1[]; |
94 | extern T arr1; |
95 | extern T arr2; |
96 | extern int arr2[]; |
97 | static_assert(sizeof(arr1) == 12, ""); |
98 | static_assert(sizeof(arr2) == 12, ""); |
99 | |
100 | // Use a failing test to ensure the type isn't considered dependent. |
101 | static_assert(sizeof(arr2) == 13, ""); // expected-error {{failed}} |
102 | } |
103 | |
104 | void g() { f<int[3]>(); } // expected-note {{in instantiation of}} |
105 | |
106 | template<typename T> void h1() { |
107 | extern T arr3; |
108 | { |
109 | int arr3; |
110 | { |
111 | extern int arr3[]; |
112 | // Detected in template definition. |
113 | (void)sizeof(arr3); // expected-error {{incomplete}} |
114 | } |
115 | } |
116 | } |
117 | |
118 | template<typename T> void h2() { |
119 | extern int arr4[3]; |
120 | { |
121 | int arr4; |
122 | { |
123 | extern T arr4; |
124 | // Detected in template instantiation. |
125 | (void)sizeof(arr4); // expected-error {{incomplete}} |
126 | } |
127 | } |
128 | } |
129 | |
130 | void i() { |
131 | h1<int[3]>(); |
132 | h2<int[]>(); // expected-note {{in instantiation of}} |
133 | } |
134 | |
135 | int arr5[3]; |
136 | template<typename T> void j() { |
137 | extern T arr5; |
138 | extern T arr6; |
139 | (void)sizeof(arr5); // expected-error {{incomplete}} |
140 | (void)sizeof(arr6); // expected-error {{incomplete}} |
141 | } |
142 | int arr6[3]; |
143 | |
144 | void k() { j<int[]>(); } // expected-note {{in instantiation of}} |
145 | |
146 | template<typename T, typename U> void l() { |
147 | extern T arrX; // expected-note {{previous}} |
148 | extern U arrX; // expected-error {{different type: 'int [4]' vs 'int [3]'}} |
149 | (void)sizeof(arrX); // expected-error {{incomplete}} |
150 | } |
151 | |
152 | void m() { |
153 | l<int[], int[3]>(); // ok |
154 | l<int[3], int[]>(); // ok |
155 | l<int[3], int[3]>(); // ok |
156 | l<int[3], int[4]>(); // expected-note {{in instantiation of}} |
157 | l<int[], int[]>(); // expected-note {{in instantiation of}} |
158 | } |
159 | |
160 | template<typename T> void n() { |
161 | extern T n_var; // expected-error {{redeclaration of 'n_var' with a different type: 'double' vs 'int'}} expected-note {{previous}} |
162 | extern T n_fn(); // expected-error {{functions that differ only in their return type cannot be overloaded}} expected-note {{previous}} |
163 | } |
164 | template void n<int>(); |
165 | template void n<double>(); // expected-note {{in instantiation of}} |
166 | |
167 | template<typename T> void o() { |
168 | extern T o_var; // expected-note {{previous}} |
169 | extern T o_fn(); // expected-note {{previous}} |
170 | } |
171 | template void o<int>(); |
172 | float o_var; // expected-error {{redefinition of 'o_var' with a different type: 'float' vs 'int'}} |
173 | float o_fn(); // expected-error {{functions that differ only in their return type cannot be overloaded}} |
174 | |
175 | int p_var; |
176 | int p_fn(); |
177 | template<typename T> void p() { |
178 | extern T p_var; |
179 | extern T p_fn(); |
180 | } |
181 | } |
182 | |
183 | namespace use_outside_ns { |
184 | namespace A { |
185 | extern int a[3]; |
186 | extern int b[]; |
187 | extern int c[3]; |
188 | void f() { |
189 | extern int a[]; |
190 | extern int b[3]; |
191 | } |
192 | template<typename T> void x() { |
193 | extern T c; |
194 | extern T d; |
195 | } |
196 | extern int d[3]; |
197 | template void x<int[]>(); |
198 | } |
199 | int w = sizeof(A::a); |
200 | int x = sizeof(A::b); // expected-error {{incomplete}} |
201 | int y = sizeof(A::c); |
202 | int z = sizeof(A::d); |
203 | namespace A { |
204 | int g() { return sizeof(a); } |
205 | int h() { return sizeof(b); } // expected-error {{incomplete}} |
206 | int i() { return sizeof(c); } |
207 | int j() { return sizeof(d); } |
208 | } |
209 | } |
210 | |
211 | extern int arr[]; |
212 | void f1() { extern int arr[2]; } // expected-note {{previous}} |
213 | void f2() { extern int arr[3]; } // expected-error {{different type: 'int [3]' vs 'int [2]'}} |
214 | |