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