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