xref: /aosp_15_r20/external/clang/test/SemaCXX/extern-c.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li 
3*67e74705SXin Li namespace test1 {
4*67e74705SXin Li   extern "C" {
test1_f()5*67e74705SXin Li     void test1_f() {
6*67e74705SXin Li       void test1_g(int);
7*67e74705SXin Li     }
8*67e74705SXin Li   }
9*67e74705SXin Li }
10*67e74705SXin Li int test1_g(int);
11*67e74705SXin Li 
12*67e74705SXin Li namespace test2 {
13*67e74705SXin Li   extern "C" {
test2_f()14*67e74705SXin Li     void test2_f() {
15*67e74705SXin Li       extern int test2_x; // expected-note {{declared with C language linkage here}}
16*67e74705SXin Li     }
17*67e74705SXin Li   }
18*67e74705SXin Li }
19*67e74705SXin Li float test2_x; // expected-error {{declaration of 'test2_x' in global scope conflicts with declaration with C language linkage}}
20*67e74705SXin Li 
21*67e74705SXin Li namespace test3 {
22*67e74705SXin Li   extern "C" {
test3_f()23*67e74705SXin Li     void test3_f() {
24*67e74705SXin Li       extern int test3_b; // expected-note {{previous declaration is here}}
25*67e74705SXin Li     }
26*67e74705SXin Li   }
27*67e74705SXin Li   extern "C" {
28*67e74705SXin Li     float test3_b; // expected-error {{redefinition of 'test3_b' with a different type: 'float' vs 'int'}}
29*67e74705SXin Li   }
30*67e74705SXin Li }
31*67e74705SXin Li 
32*67e74705SXin Li namespace N {
33*67e74705SXin Li   extern "C" {
test4_f()34*67e74705SXin Li     void test4_f() {
35*67e74705SXin Li       extern int test4_b; // expected-note {{declared with C language linkage here}}
36*67e74705SXin Li     }
37*67e74705SXin Li   }
38*67e74705SXin Li }
39*67e74705SXin Li static float test4_b; // expected-error {{declaration of 'test4_b' in global scope conflicts with declaration with C language linkage}}
40*67e74705SXin Li 
41*67e74705SXin Li extern "C" {
test4c_f()42*67e74705SXin Li   void test4c_f() {
43*67e74705SXin Li     extern int test4_c; // expected-note {{previous}}
44*67e74705SXin Li   }
45*67e74705SXin Li }
46*67e74705SXin Li static float test4_c; // expected-error {{redefinition of 'test4_c' with a different type: 'float' vs 'int'}}
47*67e74705SXin Li 
48*67e74705SXin Li namespace N {
49*67e74705SXin Li   extern "C" {
test5_f()50*67e74705SXin Li     void test5_f() {
51*67e74705SXin Li       extern int test5_b; // expected-note {{declared with C language linkage here}}
52*67e74705SXin Li     }
53*67e74705SXin Li   }
54*67e74705SXin Li }
55*67e74705SXin Li extern "C" {
56*67e74705SXin Li   static float test5_b; // expected-error {{declaration of 'test5_b' in global scope conflicts with declaration with C language linkage}}
57*67e74705SXin Li }
58*67e74705SXin Li 
59*67e74705SXin Li extern "C" {
test5c_f()60*67e74705SXin Li   void test5c_f() {
61*67e74705SXin Li     extern int test5_c; // expected-note {{previous}}
62*67e74705SXin Li   }
63*67e74705SXin Li }
64*67e74705SXin Li extern "C" {
65*67e74705SXin Li   static float test5_c; // expected-error {{redefinition of 'test5_c' with a different type: 'float' vs 'int'}}
66*67e74705SXin Li }
67*67e74705SXin Li 
68*67e74705SXin Li extern "C" {
f()69*67e74705SXin Li   void f() {
70*67e74705SXin Li     extern int test6_b;
71*67e74705SXin Li   }
72*67e74705SXin Li }
73*67e74705SXin Li namespace foo {
74*67e74705SXin Li   extern "C" {
75*67e74705SXin Li     static float test6_b;
76*67e74705SXin Li     extern float test6_b;
77*67e74705SXin Li   }
78*67e74705SXin Li }
79*67e74705SXin Li 
80*67e74705SXin Li namespace linkage {
81*67e74705SXin Li   namespace redecl {
82*67e74705SXin Li     extern "C" {
83*67e74705SXin Li       static void linkage_redecl();
84*67e74705SXin Li       static void linkage_redecl(int);
85*67e74705SXin Li       void linkage_redecl(); // ok, still not extern "C"
86*67e74705SXin Li       void linkage_redecl(int); // ok, still not extern "C"
87*67e74705SXin Li       void linkage_redecl(float); // expected-note {{previous}}
88*67e74705SXin Li       void linkage_redecl(double); // expected-error {{conflicting types}}
89*67e74705SXin Li     }
90*67e74705SXin Li   }
91*67e74705SXin Li   namespace from_outer {
92*67e74705SXin Li     void linkage_from_outer_1(); // expected-note {{previous}}
93*67e74705SXin Li     void linkage_from_outer_2(); // expected-note {{previous}}
94*67e74705SXin Li     extern "C" {
95*67e74705SXin Li       void linkage_from_outer_1(int);
96*67e74705SXin Li       void linkage_from_outer_1(); // expected-error {{different language linkage}}
97*67e74705SXin Li       void linkage_from_outer_2(); // expected-error {{different language linkage}}
98*67e74705SXin Li     }
99*67e74705SXin Li   }
100*67e74705SXin Li   namespace mixed {
101*67e74705SXin Li     extern "C" {
102*67e74705SXin Li       void linkage_mixed_1();
103*67e74705SXin Li       static void linkage_mixed_1(int);
104*67e74705SXin Li 
105*67e74705SXin Li       static void linkage_mixed_2(int);
106*67e74705SXin Li       void linkage_mixed_2();
107*67e74705SXin Li     }
108*67e74705SXin Li   }
109*67e74705SXin Li   namespace across_scopes {
110*67e74705SXin Li     namespace X {
linkage_across_scopes_f()111*67e74705SXin Li       extern "C" void linkage_across_scopes_f() {
112*67e74705SXin Li         void linkage_across_scopes_g(); // expected-note {{previous}}
113*67e74705SXin Li       }
114*67e74705SXin Li     }
115*67e74705SXin Li     namespace Y {
116*67e74705SXin Li       extern "C" void linkage_across_scopes_g(int); // expected-error {{conflicting}}
117*67e74705SXin Li     }
118*67e74705SXin Li   }
119*67e74705SXin Li }
120*67e74705SXin Li 
121*67e74705SXin Li int lookup_in_global_f; // expected-note {{here}}
122*67e74705SXin Li namespace lookup_in_global {
123*67e74705SXin Li   void lookup_in_global_f();
124*67e74705SXin Li   void lookup_in_global_g();
125*67e74705SXin Li   extern "C" {
126*67e74705SXin Li     void lookup_in_global_f(int); // expected-error {{conflicts with declaration in global scope}}
127*67e74705SXin Li     void lookup_in_global_g(int); // expected-note {{here}}
128*67e74705SXin Li   }
129*67e74705SXin Li }
130*67e74705SXin Li int lookup_in_global_g; // expected-error {{conflicts with declaration with C language linkage}}
131*67e74705SXin Li 
132*67e74705SXin Li namespace N1 {
133*67e74705SXin Li   extern "C" int different_kind_1; // expected-note {{here}}
134*67e74705SXin Li   extern "C" void different_kind_2(); // expected-note {{here}}
135*67e74705SXin Li }
136*67e74705SXin Li namespace N2 {
137*67e74705SXin Li   extern "C" void different_kind_1(); // expected-error {{different kind of symbol}}
138*67e74705SXin Li   extern "C" int different_kind_2; // expected-error {{different kind of symbol}}
139*67e74705SXin Li }
140*67e74705SXin Li 
141*67e74705SXin Li // We allow all these even though the standard says they are ill-formed.
142*67e74705SXin Li extern "C" {
143*67e74705SXin Li   struct stat {};   // expected-warning{{empty struct has size 0 in C, size 1 in C++}}
144*67e74705SXin Li   void stat(struct stat);
145*67e74705SXin Li }
146*67e74705SXin Li namespace X {
147*67e74705SXin Li   extern "C" {
148*67e74705SXin Li     void stat(struct ::stat);
149*67e74705SXin Li   }
150*67e74705SXin Li }
151*67e74705SXin Li int stat(int *p);
152*67e74705SXin Li void global_fn_vs_extern_c_var_1();
153*67e74705SXin Li namespace X {
154*67e74705SXin Li   extern "C" int global_fn_vs_extern_c_var_1;
155*67e74705SXin Li   extern "C" int global_fn_vs_extern_c_var_2;
156*67e74705SXin Li }
157*67e74705SXin Li void global_fn_vs_extern_c_var_2();
158*67e74705SXin Li void global_fn_vs_extern_c_fn_1();
159*67e74705SXin Li namespace X {
160*67e74705SXin Li   extern "C" int global_fn_vs_extern_c_fn_1(int);
161*67e74705SXin Li   extern "C" int global_fn_vs_extern_c_fn_2(int);
162*67e74705SXin Li }
163*67e74705SXin Li void global_fn_vs_extern_c_fn_2();
164*67e74705SXin Li extern "C" void name_with_using_decl_1(int);
165*67e74705SXin Li namespace using_decl {
166*67e74705SXin Li   void name_with_using_decl_1();
167*67e74705SXin Li   void name_with_using_decl_2();
168*67e74705SXin Li   void name_with_using_decl_3();
169*67e74705SXin Li }
170*67e74705SXin Li using using_decl::name_with_using_decl_1;
171*67e74705SXin Li using using_decl::name_with_using_decl_2;
172*67e74705SXin Li extern "C" void name_with_using_decl_2(int);
173*67e74705SXin Li extern "C" void name_with_using_decl_3(int);
174*67e74705SXin Li using using_decl::name_with_using_decl_3;
175*67e74705SXin Li 
176*67e74705SXin Li // We do not allow a global variable and an extern "C" function to have the same
177*67e74705SXin Li // name, because such entities may have the same mangled name.
178*67e74705SXin Li int global_var_vs_extern_c_fn_1; // expected-note {{here}}
179*67e74705SXin Li namespace X {
180*67e74705SXin Li   extern "C" void global_var_vs_extern_c_fn_1(); // expected-error {{conflicts with declaration in global scope}}
181*67e74705SXin Li   extern "C" void global_var_vs_extern_c_fn_2(); // expected-note {{here}}
182*67e74705SXin Li }
183*67e74705SXin Li int global_var_vs_extern_c_fn_2; // expected-error {{conflicts with declaration with C language linkage}}
184*67e74705SXin Li int global_var_vs_extern_c_var_1; // expected-note {{here}}
185*67e74705SXin Li namespace X {
186*67e74705SXin Li   extern "C" double global_var_vs_extern_c_var_1; // expected-error {{conflicts with declaration in global scope}}
187*67e74705SXin Li   extern "C" double global_var_vs_extern_c_var_2; // expected-note {{here}}
188*67e74705SXin Li }
189*67e74705SXin Li int global_var_vs_extern_c_var_2; // expected-error {{conflicts with declaration with C language linkage}}
190*67e74705SXin Li 
191*67e74705SXin Li template <class T> struct pr5065_n1 {};
192*67e74705SXin Li extern "C" {
193*67e74705SXin Li   union pr5065_1 {}; // expected-warning{{empty union has size 0 in C, size 1 in C++}}
194*67e74705SXin Li   struct pr5065_2 { int: 0; }; // expected-warning{{struct has size 0 in C, size 1 in C++}}
195*67e74705SXin Li   struct pr5065_3 {}; // expected-warning{{empty struct has size 0 in C, size 1 in C++}}
196*67e74705SXin Li   struct pr5065_4 { // expected-warning{{empty struct has size 0 in C, size 1 in C++}}
197*67e74705SXin Li     struct Inner {}; // expected-warning{{empty struct has size 0 in C, size 1 in C++}}
198*67e74705SXin Li   };
199*67e74705SXin Li   // These should not warn
200*67e74705SXin Li   class pr5065_n3 {};
201*67e74705SXin Li   pr5065_n1<int> pr5065_v;
mpr5065_n4202*67e74705SXin Li   struct pr5065_n4 { void m() {} };
203*67e74705SXin Li   struct pr5065_n5 : public pr5065_3 {};
204*67e74705SXin Li   struct pr5065_n6 : public virtual pr5065_3 {};
205*67e74705SXin Li }
206*67e74705SXin Li struct pr5065_n7 {};
207*67e74705SXin Li 
208*67e74705SXin Li namespace tag_hiding {
209*67e74705SXin Li   namespace namespace_with_injected_name {
210*67e74705SXin Li     class Boo {
211*67e74705SXin Li       friend struct ExternCStruct1;
212*67e74705SXin Li     };
213*67e74705SXin Li     void ExternCStruct4(); // expected-note 2{{candidate}}
214*67e74705SXin Li   }
215*67e74705SXin Li 
216*67e74705SXin Li   class Baz {
217*67e74705SXin Li     friend struct ExternCStruct2;
218*67e74705SXin Li     friend void ExternCStruct3();
219*67e74705SXin Li   };
220*67e74705SXin Li 
221*67e74705SXin Li   using namespace namespace_with_injected_name;
222*67e74705SXin Li 
223*67e74705SXin Li   extern "C" {
224*67e74705SXin Li     struct ExternCStruct1;
225*67e74705SXin Li     struct ExternCStruct2;
226*67e74705SXin Li     struct ExternCStruct3;
227*67e74705SXin Li     struct ExternCStruct4; // expected-note {{candidate}}
228*67e74705SXin Li   }
229*67e74705SXin Li   ExternCStruct1 *p1;
230*67e74705SXin Li   ExternCStruct2 *p2;
231*67e74705SXin Li   ExternCStruct3 *p3;
232*67e74705SXin Li   ExternCStruct4 *p4; // expected-error {{ambiguous}}
233*67e74705SXin Li 
234*67e74705SXin Li   extern "C" {
235*67e74705SXin Li     struct ExternCStruct1;
236*67e74705SXin Li     struct ExternCStruct2;
237*67e74705SXin Li     struct ExternCStruct3;
238*67e74705SXin Li     struct ExternCStruct4; // expected-note {{candidate}}
239*67e74705SXin Li   }
240*67e74705SXin Li   ExternCStruct1 *q1 = p1;
241*67e74705SXin Li   ExternCStruct2 *q2 = p2;
242*67e74705SXin Li   ExternCStruct3 *q3 = p3;
243*67e74705SXin Li   ExternCStruct4 *q4 = p4; // expected-error {{ambiguous}}
244*67e74705SXin Li }
245