Relax -Wcalling-convention-cast when casting to the default convention (cdecl)

llvm-svn: 269214
This commit is contained in:
Reid Kleckner 2016-05-11 17:43:13 +00:00
parent 4e8c80382f
commit 43be52a59f
2 changed files with 18 additions and 1 deletions

View File

@ -1760,7 +1760,15 @@ static void DiagnoseCallingConvCast(Sema &Self, const ExprResult &SrcExpr,
if (!FD || !FD->hasBody(Definition))
return;
// The source expression is a pointer to a known function defined in this TU.
// Only warn if we are casting from the default convention to a non-default
// convention. This can happen when the programmer forgot to apply the calling
// convention to the function definition and then inserted this cast to
// satisfy the type system.
CallingConv DefaultCC = Self.getASTContext().getDefaultCallingConvention(
FD->isVariadic(), FD->isCXXInstanceMember());
if (DstCC == DefaultCC || SrcCC != DefaultCC)
return;
// Diagnose this cast, as it is probably bad.
StringRef SrcCCName = FunctionType::getNameForCallConv(SrcCC);
StringRef DstCCName = FunctionType::getNameForCallConv(DstCC);

View File

@ -21,6 +21,10 @@ void mismatched(int x) {}
typedef void (WINAPI *callback_t)(int);
void take_callback(callback_t callback);
void WINAPI mismatched_stdcall(int x) {}
void take_opaque_fn(void (*callback)(int));
int main() {
// expected-warning@+1 {{cast between incompatible calling conventions 'cdecl' and 'stdcall'}}
take_callback((callback_t)mismatched);
@ -44,6 +48,11 @@ int main() {
// Another way to suppress the warning.
take_callback((callback_t)(void*)mismatched);
// Don't warn, because we're casting from stdcall to cdecl. Usually that means
// the programmer is rinsing the function pointer through some kind of opaque
// API.
take_opaque_fn((void (*)(int))mismatched_stdcall);
}
// MSFIXIT: fix-it:"{{.*}}callingconv-cast.c":{19:6-19:6}:"WINAPI "