Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++11 %s
      2 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions -Wno-local-type-template-args %s
      3 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions -Wno-local-type-template-args -fmodules %s
      4 
      5 namespace test1 {
      6   int x; // expected-note {{previous definition is here}}
      7   static int y;
      8   void f() {} // expected-note {{previous definition is here}}
      9 
     10   extern "C" {
     11     extern int x; // expected-error {{declaration of 'x' has a different language linkage}}
     12     extern int y; // OK, has internal linkage, so no language linkage.
     13     void f(); // expected-error {{declaration of 'f' has a different language linkage}}
     14   }
     15 }
     16 
     17 // This is OK. Both test2_f don't have language linkage since they have
     18 // internal linkage.
     19 extern "C" {
     20   static void test2_f() {
     21   }
     22   static void test2_f(int x) {
     23   }
     24 }
     25 
     26 namespace test3 {
     27   extern "C" {
     28     namespace {
     29       extern int x2;
     30       void f2();
     31     }
     32   }
     33   namespace {
     34     int x2;
     35     void f2() {}
     36   }
     37 }
     38 
     39 namespace test4 {
     40   void dummy() {
     41     void Bar();
     42     class A {
     43       friend void Bar();
     44     };
     45   }
     46 }
     47 
     48 namespace test5 {
     49   static void g();
     50   void f()
     51   {
     52     void g();
     53   }
     54 }
     55 
     56 // pr14898
     57 namespace test6 {
     58   template <class _Rp>
     59   class __attribute__ ((__visibility__("default"))) shared_future;
     60   template <class _Rp>
     61   class future {
     62     template <class> friend class shared_future;
     63     shared_future<_Rp> share();
     64   };
     65   template <class _Rp> future<_Rp>
     66   get_future();
     67   template <class _Rp>
     68   struct shared_future<_Rp&> {
     69     shared_future(future<_Rp&>&& __f);
     70   };
     71   void f() {
     72     typedef int T;
     73     get_future<int>();
     74     typedef int& U;
     75     shared_future<int&> f1 = get_future<int&>();
     76   }
     77 }
     78 
     79 // This is OK. The variables have internal linkage and therefore no language
     80 // linkage.
     81 extern "C" {
     82   static int test7_x;
     83 }
     84 extern "C++" {
     85   extern int test7_x;
     86 }
     87 extern "C++" {
     88   static int test7_y;
     89 }
     90 extern "C" {
     91   extern int test7_y;
     92 }
     93 extern "C" { typedef int test7_F(); static test7_F test7_f; }
     94 extern "C++" { extern test7_F test7_f; }
     95 
     96 // FIXME: This should be invalid. The function has no language linkage, but
     97 // the function type has, so this is redeclaring the function with a different
     98 // type.
     99 extern "C++" {
    100   static void test8_f();
    101 }
    102 extern "C" {
    103   extern void test8_f();
    104 }
    105 extern "C" {
    106   static void test8_g();
    107 }
    108 extern "C++" {
    109   extern void test8_g();
    110 }
    111 
    112 extern "C" {
    113   void __attribute__((overloadable)) test9_f(int c); // expected-note {{previous declaration is here}}
    114 }
    115 extern "C++" {
    116   void __attribute__((overloadable)) test9_f(int c); // expected-error {{declaration of 'test9_f' has a different language linkage}}
    117 }
    118 
    119 extern "C" {
    120   void __attribute__((overloadable)) test10_f(int);
    121   void __attribute__((overloadable)) test10_f(double);
    122 }
    123 
    124 extern "C" {
    125   void test11_f() {
    126     void  __attribute__((overloadable)) test11_g(int);
    127     void  __attribute__((overloadable)) test11_g(double);
    128   }
    129 }
    130 
    131 namespace test12 {
    132   const int n = 0;
    133   extern const int n;
    134   void f() {
    135     extern const int n;
    136   }
    137 }
    138 
    139 namespace test13 {
    140   static void a(void);
    141   extern void a();
    142   static void a(void) {}
    143 }
    144 
    145 namespace test14 {
    146   namespace {
    147     void a(void); // expected-note {{previous declaration is here}}
    148     static void a(void) {} // expected-error {{static declaration of 'a' follows non-static declaration}}
    149   }
    150 }
    151 
    152 namespace test15 {
    153   const int a = 5; // expected-note {{previous definition is here}}
    154   static const int a; // expected-error {{redefinition of 'a'}}
    155 }
    156 
    157 namespace test16 {
    158   extern "C" {
    159     class Foo {
    160       int x;
    161       friend int bar(Foo *y);
    162     };
    163     int bar(Foo *y) {
    164       return y->x;
    165     }
    166   }
    167 }
    168 
    169 namespace test17 {
    170   namespace {
    171     struct I {
    172     };
    173   }
    174   template <typename T1, typename T2> void foo() {}
    175   template <typename T, T x> void bar() {} // expected-note {{candidate function}}
    176   inline void *g() {
    177     struct L {
    178     };
    179     // foo<L, I>'s linkage should be the merge of UniqueExternalLinkage (or
    180     // InternalLinkage in c++11) and VisibleNoLinkage. The correct answer is
    181     // NoLinkage in both cases. This means that using foo<L, I> as a template
    182     // argument should fail.
    183     return reinterpret_cast<void*>(bar<typeof(foo<L, I>), foo<L, I> >); // expected-error {{reinterpret_cast cannot resolve overloaded function 'bar' to type 'void *}}
    184   }
    185   void h() {
    186     g();
    187   }
    188 }
    189 
    190 namespace test18 {
    191   template <typename T> struct foo {
    192     template <T *P> static void f() {}
    193     static void *g() { return (void *)f<&x>; }
    194     static T x;
    195   };
    196   template <typename T> T foo<T>::x;
    197   inline void *f() {
    198     struct S {
    199     };
    200     return foo<S>::g();
    201   }
    202   void *h() { return f(); }
    203 }
    204 
    205 extern "C" void pr16247_foo(int);
    206 static void pr16247_foo(double);
    207 void pr16247_foo(int) {}
    208 void pr16247_foo(double) {}
    209 
    210 namespace PR16247 {
    211   extern "C" void pr16247_bar(int);
    212   static void pr16247_bar(double);
    213   void pr16247_bar(int) {}
    214   void pr16247_bar(double) {}
    215 }
    216 namespace PR18964 {
    217   unsigned &*foo; //expected-error{{'foo' declared as a pointer to a reference of type}}
    218   extern struct {} *foo; // don't assert
    219 }
    220