p3.cpp revision dd9459f8869f66409f7ea429053b453e33f6499c
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  }
65}
66
67namespace test7 {
68  extern int array[100];
69  void test() {
70    extern int array[];
71    int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
72  }
73  int y = sizeof(array);
74}
75
76namespace dependent {
77  template<typename T> void f() {
78    extern int arr1[];
79    extern T arr1;
80    extern T arr2;
81    extern int arr2[];
82    static_assert(sizeof(arr1) == 12, "");
83    static_assert(sizeof(arr2) == 12, "");
84
85    // Use a failing test to ensure the type isn't considered dependent.
86    static_assert(sizeof(arr2) == 13, ""); // expected-error {{failed}}
87  }
88
89  void g() { f<int[3]>(); } // expected-note {{in instantiation of}}
90
91  template<typename T> void h1() {
92    extern T arr3;
93    {
94      int arr3;
95      {
96        extern int arr3[];
97        // Detected in template definition.
98        (void)sizeof(arr3); // expected-error {{incomplete}}
99      }
100    }
101  }
102
103  template<typename T> void h2() {
104    extern int arr4[3];
105    {
106      int arr4;
107      {
108        extern T arr4;
109        // Detected in template instantiation.
110        (void)sizeof(arr4); // expected-error {{incomplete}}
111      }
112    }
113  }
114
115  void i() {
116    h1<int[3]>();
117    h2<int[]>(); // expected-note {{in instantiation of}}
118  }
119
120  int arr5[3];
121  template<typename T> void j() {
122    extern T arr5;
123    extern T arr6;
124    (void)sizeof(arr5); // expected-error {{incomplete}}
125    (void)sizeof(arr6); // expected-error {{incomplete}}
126  }
127  int arr6[3];
128
129  void k() { j<int[]>(); } // expected-note {{in instantiation of}}
130
131  template<typename T, typename U> void l() {
132    extern T arrX; // expected-note {{previous}}
133    extern U arrX; // expected-error {{different type: 'int [4]' vs 'int [3]'}}
134    (void)sizeof(arrX); // expected-error {{incomplete}}
135  }
136
137  void m() {
138    l<int[], int[3]>(); // ok
139    l<int[3], int[]>(); // ok
140    l<int[3], int[3]>(); // ok
141    l<int[3], int[4]>(); // expected-note {{in instantiation of}}
142    l<int[], int[]>(); // expected-note {{in instantiation of}}
143  }
144
145  template<typename T> void n() {
146    extern T n_var;
147  }
148  template void n<int>();
149  // FIXME: Diagnose this!
150  float n_var;
151  template void n<double>();
152}
153