214 lines
5.9 KiB
C++
214 lines
5.9 KiB
C++
|
// 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]'}}
|