From 9fde2e013ee0892ef02f9278db4ff4de270b970a Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 26 Feb 2015 19:43:46 +0000 Subject: [PATCH] Win64: Silently ignore __stdcall, __fastcall, and __thiscall MSVC doesn't warn on this. Users are expected to apply the WINAPI macro to functions passed by pointer to the Win32 API, and this macro expands to __stdcall. This means we end up with a lot of useless noisy warnings about ignored calling conventions when compiling code with clang for Win64. llvm-svn: 230668 --- clang/include/clang/Basic/TargetInfo.h | 3 ++- clang/lib/Basic/Targets.cpp | 20 ++++++++++++++++---- clang/lib/Sema/SemaDeclAttr.cpp | 7 +++++-- clang/test/Sema/MicrosoftCompatibility-x64.c | 13 +++++++++---- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index e00e0f5..bda132e 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -842,7 +842,8 @@ public: enum CallingConvCheckResult { CCCR_OK, - CCCR_Warning + CCCR_Warning, + CCCR_Ignore, }; /// \brief Determines whether a given calling convention is valid for the diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 03cd853..a7c8413 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -3626,19 +3626,31 @@ public: IntPtrType = SignedLongLong; this->UserLabelPrefix = ""; } + void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { WindowsTargetInfo::getTargetDefines(Opts, Builder); Builder.defineMacro("_WIN64"); } + BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { - return (CC == CC_C || - CC == CC_X86VectorCall || - CC == CC_IntelOclBicc || - CC == CC_X86_64SysV) ? CCCR_OK : CCCR_Warning; + switch (CC) { + case CC_X86StdCall: + case CC_X86ThisCall: + case CC_X86FastCall: + return CCCR_Ignore; + case CC_C: + case CC_X86VectorCall: + case CC_IntelOclBicc: + case CC_X86_64SysV: + return CCCR_OK; + default: + return CCCR_Warning; + } } }; } // end anonymous namespace diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 7af4bd2..4552ad9 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3393,9 +3393,12 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, const TargetInfo &TI = Context.getTargetInfo(); TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC); - if (A == TargetInfo::CCCR_Warning) { - Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName(); + if (A != TargetInfo::CCCR_OK) { + if (A == TargetInfo::CCCR_Warning) + Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName(); + // This convention is not valid for the target. Use the default function or + // method calling convention. TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown; if (FD) MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member : diff --git a/clang/test/Sema/MicrosoftCompatibility-x64.c b/clang/test/Sema/MicrosoftCompatibility-x64.c index bf595af..7d1f649 100644 --- a/clang/test/Sema/MicrosoftCompatibility-x64.c +++ b/clang/test/Sema/MicrosoftCompatibility-x64.c @@ -1,8 +1,13 @@ -// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility -triple x86_64-pc-win32 -int __stdcall f(void); /* expected-warning {{calling convention '__stdcall' ignored for this target}} */ +// RUN: %clang_cc1 %s -Wmicrosoft -verify -fms-compatibility -triple x86_64-pc-win32 -/* This should compile without warning because __stdcall is treated -as __cdecl in MS compatibility mode for x64 compiles*/ +// None of these should warn. stdcall is treated as equivalent to cdecl on +// x64. +// expected-no-diagnostics + +int __stdcall f(void); int __cdecl f(void) { return 0; } +int __stdcall func_std(void); +int __thiscall func_this(void); +int __fastcall func_fast(void); -- 2.7.4