Clang Project

clang_source_code/test/SemaCXX/linkage2.cpp
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
5namespace 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.
19extern "C" {
20  static void test2_f() {
21  }
22  static void test2_f(int x) {
23  }
24}
25
26namespace 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
39namespace test4 {
40  void dummy() {
41    void Bar();
42    class A {
43      friend void Bar();
44    };
45  }
46}
47
48namespace test5 {
49  static void g();
50  void f()
51  {
52    void g();
53  }
54}
55
56// pr14898
57namespace 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.
81extern "C" {
82  static int test7_x;
83}
84extern "C++" {
85  extern int test7_x;
86}
87extern "C++" {
88  static int test7_y;
89}
90extern "C" {
91  extern int test7_y;
92}
93extern "C" { typedef int test7_F(); static test7_F test7_f; }
94extern "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.
99extern "C++" {
100  static void test8_f();
101}
102extern "C" {
103  extern void test8_f();
104}
105extern "C" {
106  static void test8_g();
107}
108extern "C++" {
109  extern void test8_g();
110}
111
112extern "C" {
113  void __attribute__((overloadable)) test9_f(int c); // expected-note {{previous declaration is here}}
114}
115extern "C++" {
116  void __attribute__((overloadable)) test9_f(int c); // expected-error {{declaration of 'test9_f' has a different language linkage}}
117}
118
119extern "C" {
120  void __attribute__((overloadable)) test10_f(int);
121  void __attribute__((overloadable)) test10_f(double);
122}
123
124extern "C" {
125  void test11_f() {
126    void  __attribute__((overloadable)) test11_g(int);
127    void  __attribute__((overloadable)) test11_g(double);
128  }
129}
130
131namespace test12 {
132  const int n = 0;
133  extern const int n;
134  void f() {
135    extern const int n;
136  }
137}
138
139namespace test13 {
140  static void a(void);
141  extern void a();
142  static void a(void) {}
143}
144
145namespace test14 {
146  // Anonymous namespace implies internal linkage, so 'static' has no effect.
147  namespace {
148    void a(void);
149    static void a(void) {}
150  }
151}
152
153namespace test15 {
154  const int a = 5; // expected-note {{previous definition is here}}
155  static const int a; // expected-error {{redefinition of 'a'}}
156}
157
158namespace test16 {
159  extern "C" {
160    class Foo {
161      int x;
162      friend int bar(Foo *y);
163    };
164    int bar(Foo *y) {
165      return y->x;
166    }
167  }
168}
169
170namespace test17 {
171  namespace {
172    struct I {
173    };
174  }
175  template <typename T1, typename T2> void foo() {}
176  template <typename T, T x> void bar() {} // expected-note {{candidate function}}
177  inline void *g() {
178    struct L {
179    };
180    // foo<L, I>'s linkage should be the merge of UniqueExternalLinkage (or
181    // InternalLinkage in c++11) and VisibleNoLinkage. The correct answer is
182    // NoLinkage in both cases. This means that using foo<L, I> as a template
183    // argument should fail.
184    return reinterpret_cast<void*>(bar<typeof(foo<L, I>), foo<L, I> >); // expected-error {{reinterpret_cast cannot resolve overloaded function 'bar' to type 'void *}}
185  }
186  void h() {
187    g();
188  }
189}
190
191namespace test18 {
192  template <typename T> struct foo {
193    template <T *P> static void f() {}
194    static void *g() { return (void *)f<&x>; }
195    static T x;
196  };
197  template <typename T> T foo<T>::x;
198  inline void *f() {
199    struct S {
200    };
201    return foo<S>::g();
202  }
203  void *h() { return f(); }
204}
205
206extern "C" void pr16247_foo(int);
207static void pr16247_foo(double);
208void pr16247_foo(int) {}
209void pr16247_foo(double) {}
210
211namespace PR16247 {
212  extern "C" void pr16247_bar(int);
213  static void pr16247_bar(double);
214  void pr16247_bar(int) {}
215  void pr16247_bar(double) {}
216}
217namespace PR18964 {
218  unsigned &*foo; //expected-error{{'foo' declared as a pointer to a reference of type}}
219  extern struct {} *foo; // don't assert
220}
221
222namespace typedef_name_for_linkage {
223  template<typename T> struct Use {};
224
225  struct A { A(); A(const A&); ~A(); };
226
227  typedef struct {
228    A a;
229  } B;
230
231  struct C {
232    typedef struct {
233      A a;
234    } D;
235  };
236
237  typedef struct {
238    void f() { static int n; struct Inner {};}
239  } E;
240
241  // FIXME: Ideally this would be accepted in all modes. In C++98, we trigger a
242  // linkage calculation to drive the "internal linkage type as template
243  // argument" warning.
244  typedef struct {
245    void f() { struct Inner {}; Use<Inner> ui; }
246  } F;
247#if __cplusplus < 201103L
248  // expected-error@-2 {{unsupported: typedef changes linkage of anonymous type, but linkage was already computed}}
249  // expected-note@-5 {{use a tag name here}}
250#endif
251}
252