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