// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1y -triple x86_64-linux-gnu %s // If there is a preceding declaration of the entity *in the same scope* in // which the bound was specified, an omitted array bound is taken to be the // same as in that earlier declaration // rdar://13535367 namespace test0 { extern "C" int array[]; void declare() { extern int array[100]; } int value1 = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} extern "C" int array[]; int value2 = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} } namespace test1 { extern "C" int array[]; void test() { { extern int array[100]; } extern int array[]; int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} } } namespace test2 { void declare() { extern int array[100]; } extern int array[]; int value = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} } namespace test3 { void test() { { extern int array[100]; } extern int array[]; int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} } } namespace test4 { extern int array[]; void test() { extern int array[100]; int x = sizeof(array); } int y = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} } namespace test5 { void test() { extern int array[100]; extern int array[]; int x = sizeof(array); } } namespace test6 { void test() { extern int array[100]; { extern int array[]; int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} } int y = sizeof(array); extern int array[]; int z = sizeof(array); } } namespace test7 { extern int array[100]; void test() { extern int array[]; int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} } int y = sizeof(array); extern int array[]; int z = sizeof(array); } namespace test8 { extern int array[]; void test() { extern int array[100]; int x = sizeof(array); } int y = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} extern int array[]; int z = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}} } namespace dependent { template<typename T> void f() { extern int arr1[]; extern T arr1; extern T arr2; extern int arr2[]; static_assert(sizeof(arr1) == 12, ""); static_assert(sizeof(arr2) == 12, ""); // Use a failing test to ensure the type isn't considered dependent. static_assert(sizeof(arr2) == 13, ""); // expected-error {{failed}} } void g() { f<int[3]>(); } // expected-note {{in instantiation of}} template<typename T> void h1() { extern T arr3; { int arr3; { extern int arr3[]; // Detected in template definition. (void)sizeof(arr3); // expected-error {{incomplete}} } } } template<typename T> void h2() { extern int arr4[3]; { int arr4; { extern T arr4; // Detected in template instantiation. (void)sizeof(arr4); // expected-error {{incomplete}} } } } void i() { h1<int[3]>(); h2<int[]>(); // expected-note {{in instantiation of}} } int arr5[3]; template<typename T> void j() { extern T arr5; extern T arr6; (void)sizeof(arr5); // expected-error {{incomplete}} (void)sizeof(arr6); // expected-error {{incomplete}} } int arr6[3]; void k() { j<int[]>(); } // expected-note {{in instantiation of}} template<typename T, typename U> void l() { extern T arrX; // expected-note {{previous}} extern U arrX; // expected-error {{different type: 'int [4]' vs 'int [3]'}} (void)sizeof(arrX); // expected-error {{incomplete}} } void m() { l<int[], int[3]>(); // ok l<int[3], int[]>(); // ok l<int[3], int[3]>(); // ok l<int[3], int[4]>(); // expected-note {{in instantiation of}} l<int[], int[]>(); // expected-note {{in instantiation of}} } template<typename T> void n() { extern T n_var; // expected-error {{redeclaration of 'n_var' with a different type: 'double' vs 'int'}} expected-note {{previous}} extern T n_fn(); // expected-error {{functions that differ only in their return type cannot be overloaded}} expected-note {{previous}} } template void n<int>(); template void n<double>(); // expected-note {{in instantiation of}} template<typename T> void o() { extern T o_var; // expected-note {{previous}} extern T o_fn(); // expected-note {{previous}} } template void o<int>(); float o_var; // expected-error {{redefinition of 'o_var' with a different type: 'float' vs 'int'}} float o_fn(); // expected-error {{functions that differ only in their return type cannot be overloaded}} int p_var; int p_fn(); template<typename T> void p() { extern T p_var; extern T p_fn(); } } namespace use_outside_ns { namespace A { extern int a[3]; extern int b[]; extern int c[3]; void f() { extern int a[]; extern int b[3]; } template<typename T> void x() { extern T c; extern T d; } extern int d[3]; template void x<int[]>(); } int w = sizeof(A::a); int x = sizeof(A::b); // expected-error {{incomplete}} int y = sizeof(A::c); int z = sizeof(A::d); namespace A { int g() { return sizeof(a); } int h() { return sizeof(b); } // expected-error {{incomplete}} int i() { return sizeof(c); } int j() { return sizeof(d); } } } extern int arr[]; void f1() { extern int arr[2]; } // expected-note {{previous}} void f2() { extern int arr[3]; } // expected-error {{different type: 'int [3]' vs 'int [2]'}}