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
8namespace 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
16namespace 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
25namespace 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
31namespace 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
39namespace 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
48namespace test5 {
49  void test() {
50    extern int array[100];
51    extern int array[];
52    int x = sizeof(array);
53  }
54}
55
56namespace 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
69namespace 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
80namespace 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
91namespace 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 {{redefinition 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
183namespace 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