xref: /minix3/external/bsd/llvm/dist/clang/test/SemaCXX/function-extern-c.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -Wreturn-type -fsyntax-only -std=c++11 -verify %s
2*f4a2713aSLionel Sambuc 
3*f4a2713aSLionel Sambuc class A {
4*f4a2713aSLionel Sambuc public:
5*f4a2713aSLionel Sambuc   A(const A&);
6*f4a2713aSLionel Sambuc };
7*f4a2713aSLionel Sambuc 
8*f4a2713aSLionel Sambuc struct S {
9*f4a2713aSLionel Sambuc   int i;
10*f4a2713aSLionel Sambuc   double d;
11*f4a2713aSLionel Sambuc 
BS12*f4a2713aSLionel Sambuc   virtual void B() {}
13*f4a2713aSLionel Sambuc };
14*f4a2713aSLionel Sambuc 
15*f4a2713aSLionel Sambuc union U {
16*f4a2713aSLionel Sambuc   struct {
17*f4a2713aSLionel Sambuc     int i;
BU::__anon97f84597010818*f4a2713aSLionel Sambuc     virtual void B() {} // Can only do this in C++11
19*f4a2713aSLionel Sambuc   } t;
20*f4a2713aSLionel Sambuc };
21*f4a2713aSLionel Sambuc 
22*f4a2713aSLionel Sambuc struct S2 {
23*f4a2713aSLionel Sambuc   int i;
24*f4a2713aSLionel Sambuc   double d;
25*f4a2713aSLionel Sambuc };
26*f4a2713aSLionel Sambuc 
27*f4a2713aSLionel Sambuc extern "C" U f3( void ); // expected-warning {{'f3' has C-linkage specified, but returns user-defined type 'U' which is incompatible with C}}
28*f4a2713aSLionel Sambuc extern "C" S f0(void); // expected-warning {{'f0' has C-linkage specified, but returns user-defined type 'S' which is incompatible with C}}
29*f4a2713aSLionel Sambuc extern "C" A f4( void ); // expected-warning {{'f4' has C-linkage specified, but returns user-defined type 'A' which is incompatible with C}}
30*f4a2713aSLionel Sambuc 
31*f4a2713aSLionel Sambuc // These should all be fine
32*f4a2713aSLionel Sambuc extern "C" S2 f5( void );
33*f4a2713aSLionel Sambuc extern "C" void f2( A x );
34*f4a2713aSLionel Sambuc extern "C" void f6( S s );
35*f4a2713aSLionel Sambuc extern "C" void f7( U u );
36*f4a2713aSLionel Sambuc extern "C" double f8(void);
37*f4a2713aSLionel Sambuc extern "C" long long f11( void );
38*f4a2713aSLionel Sambuc extern "C" A *f10( void );
39*f4a2713aSLionel Sambuc 
40*f4a2713aSLionel Sambuc extern "C" struct mypodstruct f12(); // expected-warning {{'f12' has C-linkage specified, but returns incomplete type 'struct mypodstruct' which could be incompatible with C}}
41*f4a2713aSLionel Sambuc 
42*f4a2713aSLionel Sambuc namespace test2 {
43*f4a2713aSLionel Sambuc   // FIXME: we should probably suppress the first warning as the second one
44*f4a2713aSLionel Sambuc   // is more precise.
45*f4a2713aSLionel Sambuc   // For now this tests that a second 'extern "C"' is not necessary to trigger
46*f4a2713aSLionel Sambuc   // the warning.
47*f4a2713aSLionel Sambuc   struct A;
48*f4a2713aSLionel Sambuc   extern "C" A f(void); // expected-warning {{'f' has C-linkage specified, but returns incomplete type 'test2::A' which could be incompatible with C}}
49*f4a2713aSLionel Sambuc   struct A {
50*f4a2713aSLionel Sambuc     A(const A&);
51*f4a2713aSLionel Sambuc   };
52*f4a2713aSLionel Sambuc   A f(void);  // no warning. warning is already issued on first declaration.
53*f4a2713aSLionel Sambuc }
54*f4a2713aSLionel Sambuc 
55*f4a2713aSLionel Sambuc namespace test3 {
56*f4a2713aSLionel Sambuc   struct A {
57*f4a2713aSLionel Sambuc     A(const A&);
58*f4a2713aSLionel Sambuc   };
59*f4a2713aSLionel Sambuc   extern "C" {
60*f4a2713aSLionel Sambuc     // Don't warn for static functions.
61*f4a2713aSLionel Sambuc     static A f(void);
62*f4a2713aSLionel Sambuc   }
63*f4a2713aSLionel Sambuc }
64*f4a2713aSLionel Sambuc 
65*f4a2713aSLionel Sambuc // rdar://13364028
66*f4a2713aSLionel Sambuc namespace rdar13364028 {
67*f4a2713aSLionel Sambuc class A {
68*f4a2713aSLionel Sambuc public:
69*f4a2713aSLionel Sambuc     virtual int x();
70*f4a2713aSLionel Sambuc };
71*f4a2713aSLionel Sambuc 
72*f4a2713aSLionel Sambuc extern "C" {
73*f4a2713aSLionel Sambuc #pragma clang diagnostic push
74*f4a2713aSLionel Sambuc #pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
75*f4a2713aSLionel Sambuc A xyzzy();
76*f4a2713aSLionel Sambuc #pragma clang diagnostic pop
77*f4a2713aSLionel Sambuc A bbb(); // expected-warning {{'bbb' has C-linkage specified, but returns user-defined type 'rdar13364028::A' which is incompatible with C}}
ccc()78*f4a2713aSLionel Sambuc A ccc() { // expected-warning {{'ccc' has C-linkage specified, but returns user-defined type 'rdar13364028::A' which is incompatible with C}}
79*f4a2713aSLionel Sambuc   return A();
80*f4a2713aSLionel Sambuc };
81*f4a2713aSLionel Sambuc }
82*f4a2713aSLionel Sambuc 
83*f4a2713aSLionel Sambuc A xyzzy();
84*f4a2713aSLionel Sambuc 
xyzzy()85*f4a2713aSLionel Sambuc A xyzzy()
86*f4a2713aSLionel Sambuc {
87*f4a2713aSLionel Sambuc   return A();
88*f4a2713aSLionel Sambuc }
89*f4a2713aSLionel Sambuc 
bbb()90*f4a2713aSLionel Sambuc A bbb()
91*f4a2713aSLionel Sambuc {
92*f4a2713aSLionel Sambuc   return A();
93*f4a2713aSLionel Sambuc }
94*f4a2713aSLionel Sambuc 
95*f4a2713aSLionel Sambuc A bbb();
96*f4a2713aSLionel Sambuc 
97*f4a2713aSLionel Sambuc A ccc();
98*f4a2713aSLionel Sambuc }
99