xref: /llvm-project/clang/test/CXX/dcl.decl/dcl.meaning/dcl.array/p3.cpp (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
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 namespace test0 {
8   extern "C" int array[];
declare()9   void declare() { extern int array[100]; }
10   int value1 = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int[]'}}
11   extern "C" int array[];
12   int value2 = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int[]'}}
13 }
14 
15 namespace test1 {
16   extern "C" int array[];
test()17   void test() {
18     { extern int array[100]; }
19     extern int array[];
20     int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int[]'}}
21   }
22 }
23 
24 namespace test2 {
declare()25   void declare() { extern int array[100]; }
26   extern int array[];
27   int value = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int[]'}}
28 }
29 
30 namespace test3 {
test()31   void test() {
32     { extern int array[100]; }
33     extern int array[];
34     int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int[]'}}
35   }
36 }
37 
38 namespace test4 {
39   extern int array[];
test()40   void test() {
41     extern int array[100];
42     int x = sizeof(array);
43   }
44   int y = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int[]'}}
45 }
46 
47 namespace test5 {
test()48   void test() {
49     extern int array[100];
50     extern int array[];
51     int x = sizeof(array);
52   }
53 }
54 
55 namespace test6 {
test()56   void test() {
57     extern int array[100];
58     {
59       extern int array[];
60       int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int[]'}}
61     }
62     int y = sizeof(array);
63     extern int array[];
64     int z = sizeof(array);
65   }
66 }
67 
68 namespace test7 {
69   extern int array[100];
test()70   void test() {
71     extern int array[];
72     int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int[]'}}
73   }
74   int y = sizeof(array);
75   extern int array[];
76   int z = sizeof(array);
77 }
78 
79 namespace test8 {
80   extern int array[];
test()81   void test() {
82     extern int array[100];
83     int x = sizeof(array);
84   }
85   int y = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int[]'}}
86   extern int array[];
87   int z = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int[]'}}
88 }
89 
90 namespace dependent {
f()91   template<typename T> void f() {
92     extern int arr1[];
93     extern T arr1;
94     extern T arr2;
95     extern int arr2[];
96     static_assert(sizeof(arr1) == 12, "");
97     static_assert(sizeof(arr2) == 12, "");
98 
99     // Use a failing test to ensure the type isn't considered dependent.
100     static_assert(sizeof(arr2) == 13, ""); // expected-error {{failed}} \
101                                            // expected-note {{evaluates to '12 == 13'}}
102   }
103 
g()104   void g() { f<int[3]>(); } // expected-note {{in instantiation of}}
105 
h1()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 
h2()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 
i()130   void i() {
131     h1<int[3]>();
132     h2<int[]>(); // expected-note {{in instantiation of}}
133   }
134 
135   int arr5[3];
j()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 
k()144   void k() { j<int[]>(); } // expected-note {{in instantiation of}}
145 
l()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 
m()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 
n()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 
o()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();
p()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];
f()188     void f() {
189       extern int a[];
190       extern int b[3];
191     }
x()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 {
g()204     int g() { return sizeof(a); }
h()205     int h() { return sizeof(b); } // expected-error {{incomplete}}
i()206     int i() { return sizeof(c); }
j()207     int j() { return sizeof(d); }
208   }
209 }
210 
211 extern int arr[];
f1()212 void f1() { extern int arr[2]; } // expected-note {{previous}}
f2()213 void f2() { extern int arr[3]; } // expected-error {{different type: 'int[3]' vs 'int[2]'}}
214