зеркало из https://github.com/microsoft/clang-1.git
Adding support for warning when a non-C compatible user-defined type is returned from an extern "C" function.
Fixes bug 6143 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150128 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
7f99f43b36
Коммит
2c0bf24370
|
@ -163,7 +163,9 @@ def warn_parameter_size: Warning<
|
|||
def warn_return_value_size: Warning<
|
||||
"return value of %0 is a large (%1 bytes) pass-by-value object; "
|
||||
"pass it by reference instead ?">, InGroup<LargeByValueCopy>;
|
||||
|
||||
def warn_return_value_udt: Warning<
|
||||
"%0 has C-linkage specified, but returns user-defined type %1 which is "
|
||||
"incompatible with C">, InGroup<ReturnType>;
|
||||
def warn_implicit_function_decl : Warning<
|
||||
"implicit declaration of function %0">,
|
||||
InGroup<ImplicitFunctionDeclare>, DefaultIgnore;
|
||||
|
|
|
@ -5774,6 +5774,17 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
|
|||
Context.BuiltinInfo.ForgetBuiltin(BuiltinID, Context.Idents);
|
||||
}
|
||||
}
|
||||
|
||||
// If this function is declared as being extern "C", then check to see if
|
||||
// the function returns a UDT (class, struct, or union type) that is not C
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
return Redeclaration;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
// RUN: %clang_cc1 -Wreturn-type -fsyntax-only -std=c++11 -verify %s
|
||||
|
||||
class A {
|
||||
public:
|
||||
A(const A&);
|
||||
};
|
||||
|
||||
struct S {
|
||||
int i;
|
||||
double d;
|
||||
|
||||
virtual void B() {}
|
||||
};
|
||||
|
||||
union U {
|
||||
struct {
|
||||
int i;
|
||||
virtual void B() {} // Can only do this in C++11
|
||||
} t;
|
||||
};
|
||||
|
||||
struct S2 {
|
||||
int i;
|
||||
double d;
|
||||
};
|
||||
|
||||
extern "C" U f3( void ); // expected-warning {{'f3' has C-linkage specified, but returns user-defined type 'U' which is incompatible with C}}
|
||||
extern "C" S f0(void); // expected-warning {{'f0' has C-linkage specified, but returns user-defined type 'S' which is incompatible with C}}
|
||||
extern "C" A f4( void ); // expected-warning {{'f4' has C-linkage specified, but returns user-defined type 'A' which is incompatible with C}}
|
||||
|
||||
// These should all be fine
|
||||
extern "C" S2 f5( void );
|
||||
extern "C" void f2( A x );
|
||||
extern "C" void f6( S s );
|
||||
extern "C" void f7( U u );
|
||||
extern "C" double f8(void);
|
||||
extern "C" long long f11( void );
|
||||
extern "C" A *f10( void );
|
Загрузка…
Ссылка в новой задаче