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 | // Anonymous namespace implies internal linkage, so 'static' has no effect. |
147 | namespace { |
148 | void a(void); |
149 | static void a(void) {} |
150 | } |
151 | } |
152 | |
153 | namespace test15 { |
154 | const int a = 5; // expected-note {{previous definition is here}} |
155 | static const int a; // expected-error {{redefinition of 'a'}} |
156 | } |
157 | |
158 | namespace 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 | |
170 | namespace 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 | |
191 | namespace 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 | |
206 | extern "C" void pr16247_foo(int); |
207 | static void pr16247_foo(double); |
208 | void pr16247_foo(int) {} |
209 | void pr16247_foo(double) {} |
210 | |
211 | namespace 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 | } |
217 | namespace 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 | |
222 | namespace 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 | |