From: Reid Kleckner Date: Mon, 3 Nov 2014 21:24:50 +0000 (+0000) Subject: Don't diagnose no-prototype callee-cleanup function definitions X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=734e0ab01d133dc07f3c67b116894a4b1bb0be3c;p=clang Don't diagnose no-prototype callee-cleanup function definitions We already have a warning on the call sites of code like this: void f() { } void g() { f(1, 2, 3); } t.c:2:21: warning: too many arguments in call to 'f' We can limit ourselves to diagnosing unprototyped forward declarations of f to cut down on noise. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221184 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index fe5981121f..b9f8f637e2 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -7383,6 +7383,21 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!NewFD->isInvalidDecl() && NewFD->isMSVCRTEntryPoint()) CheckMSVCRTEntryPoint(NewFD); + // Diagnose no-prototype function declarations with calling conventions that + // don't support variadic calls. + const FunctionType *FT = R->castAs(); + if (FT->isFunctionNoProtoType() && !D.isFunctionDefinition()) { + CallingConv CC = FT->getExtInfo().getCC(); + if (!supportsVariadicCall(CC)) { + // Windows system headers sometimes accidentally use stdcall without + // (void) parameters, so we relax this to a warning. + int DiagID = + CC == CC_X86StdCall ? diag::warn_cconv_knr : diag::err_cconv_knr; + Diag(NewFD->getLocation(), DiagID) + << FunctionType::getNameForCallConv(CC); + } + } + if (!NewFD->isInvalidDecl()) D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization)); @@ -7948,21 +7963,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // Semantic checking for this function declaration (in isolation). - // Diagnose calling conventions that don't support variadic calls. - QualType NewQType = Context.getCanonicalType(NewFD->getType()); - const FunctionType *NewType = cast(NewQType); - if (isa(NewType)) { - FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo(); - if (!supportsVariadicCall(NewTypeInfo.getCC())) { - // Windows system headers sometimes accidentally use stdcall without - // (void) parameters, so use a default-error warning in this case :-/ - int DiagID = NewTypeInfo.getCC() == CC_X86StdCall - ? diag::warn_cconv_knr : diag::err_cconv_knr; - Diag(NewFD->getLocation(), DiagID) - << FunctionType::getNameForCallConv(NewTypeInfo.getCC()); - } - } - if (getLangOpts().CPlusPlus) { // C++-specific checks. if (CXXConstructorDecl *Constructor = dyn_cast(NewFD)) { diff --git a/test/Sema/callingconv.c b/test/Sema/callingconv.c index 5ac5a4ad04..6a8be5ae05 100644 --- a/test/Sema/callingconv.c +++ b/test/Sema/callingconv.c @@ -10,7 +10,7 @@ void __attribute__((stdcall)) bar(float *a) { void __attribute__((fastcall(1))) baz(float *a) { // expected-error {{'fastcall' attribute takes no arguments}} } -void __attribute__((fastcall)) test0() { // expected-error {{function with no prototype cannot use the fastcall calling convention}} +void __attribute__((fastcall)) test0() { } void __attribute__((fastcall)) test1(void) { diff --git a/test/Sema/decl-microsoft-call-conv.c b/test/Sema/decl-microsoft-call-conv.c index c8fb6e10f9..cefaf4f40b 100644 --- a/test/Sema/decl-microsoft-call-conv.c +++ b/test/Sema/decl-microsoft-call-conv.c @@ -14,11 +14,17 @@ void __pascal CrcGenerateTablePascal() {} void __vectorcall CrcGenerateTableVectorcall(void); void __vectorcall CrcGenerateTableVectorcall() {} -void __fastcall CrcGenerateTableNoProtoFastcall() {} // expected-error{{function with no prototype cannot use the fastcall calling convention}} -void __stdcall CrcGenerateTableNoProtoStdcall() {} // expected-warning{{function with no prototype cannot use the stdcall calling convention}} -void __thiscall CrcGenerateTableNoProtoThiscall() {} // expected-error{{function with no prototype cannot use the thiscall calling convention}} -void __pascal CrcGenerateTableNoProtoPascal() {} // expected-error{{function with no prototype cannot use the pascal calling convention}} -void __vectorcall CrcGenerateTableNoProtoVectorcall() {} // expected-error{{function with no prototype cannot use the vectorcall calling convention}} +void __fastcall CrcGenerateTableNoProtoFastcall(); // expected-error{{function with no prototype cannot use the fastcall calling convention}} +void __stdcall CrcGenerateTableNoProtoStdcall(); // expected-warning{{function with no prototype cannot use the stdcall calling convention}} +void __thiscall CrcGenerateTableNoProtoThiscall(); // expected-error{{function with no prototype cannot use the thiscall calling convention}} +void __pascal CrcGenerateTableNoProtoPascal(); // expected-error{{function with no prototype cannot use the pascal calling convention}} +void __vectorcall CrcGenerateTableNoProtoVectorcall(); // expected-error{{function with no prototype cannot use the vectorcall calling convention}} + +void __fastcall CrcGenerateTableNoProtoDefFastcall() {} +void __stdcall CrcGenerateTableNoProtoDefStdcall() {} +void __thiscall CrcGenerateTableNoProtoDefThiscall() {} +void __pascal CrcGenerateTableNoProtoDefPascal() {} +void __vectorcall CrcGenerateTableNoProtoDefVectorcall() {} // Regular calling convention is fine. void CrcGenerateTableNoProto() {}