Home | History | Annotate | Download | only in dcl.array
      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
      8 namespace 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 
     16 namespace 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 
     25 namespace 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 
     31 namespace 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 
     39 namespace 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 
     48 namespace test5 {
     49   void test() {
     50     extern int array[100];
     51     extern int array[];
     52     int x = sizeof(array);
     53   }
     54 }
     55 
     56 namespace 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 
     69 namespace 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 
     80 namespace 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 
     91 namespace 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 {{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 
    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 
    183 namespace 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 
    211 extern int arr[];
    212 void f1() { extern int arr[2]; } // expected-note {{previous}}
    213 void f2() { extern int arr[3]; } // expected-error {{different type: 'int [3]' vs 'int [2]'}}
    214