diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5c3f1150c36a..67f43d22c814 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -192,6 +192,9 @@ def warn_return_value_size: Warning< def warn_return_value_udt: Warning< "%0 has C-linkage specified, but returns user-defined type %1 which is " "incompatible with C">, InGroup; +def warn_return_value_udt_incomplete: Warning< + "%0 has C-linkage specified, but returns incomplete type %1 which could be " + "incompatible with C">, InGroup; def warn_implicit_function_decl : Warning< "implicit declaration of function %0">, InGroup, DefaultIgnore; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 52aa5b72d197..12444e555941 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6086,10 +6086,11 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // compatible, and if it does, warn the user. if (NewFD->isExternC()) { QualType R = NewFD->getResultType(); - if (!R.isPODType(Context) && - !R->isVoidType()) - Diag( NewFD->getLocation(), diag::warn_return_value_udt ) - << NewFD << R; + if (R->isIncompleteType() && !R->isVoidType()) + Diag(NewFD->getLocation(), diag::warn_return_value_udt_incomplete) + << NewFD << R; + else if (!R.isPODType(Context) && !R->isVoidType()) + Diag(NewFD->getLocation(), diag::warn_return_value_udt) << NewFD << R; } } return Redeclaration; diff --git a/clang/test/SemaCXX/function-extern-c.cpp b/clang/test/SemaCXX/function-extern-c.cpp index f20cd38a3cb0..16dbbb26fc66 100644 --- a/clang/test/SemaCXX/function-extern-c.cpp +++ b/clang/test/SemaCXX/function-extern-c.cpp @@ -36,3 +36,5 @@ extern "C" void f7( U u ); extern "C" double f8(void); extern "C" long long f11( void ); extern "C" A *f10( void ); + +extern "C" struct mypodstruct f12(); // expected-warning {{'f12' has C-linkage specified, but returns incomplete type 'struct mypodstruct' which could be incompatible with C}}