r365579 - [MS] Treat ignored explicit calling conventions as an explicit __cdecl
Reid Kleckner via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 9 16:17:43 PDT 2019
Author: rnk
Date: Tue Jul 9 16:17:43 2019
New Revision: 365579
URL: http://llvm.org/viewvc/llvm-project?rev=365579&view=rev
Log:
[MS] Treat ignored explicit calling conventions as an explicit __cdecl
The CCCR_Ignore action is only used for Microsoft calling conventions,
mainly because MSVC does not warn when a calling convention would be
ignored by the current target. This behavior is actually somewhat
important, since windows.h uses WINAPI (which expands to __stdcall)
widely. This distinction didn't matter much before the introduction of
__vectorcall to x64 and the ability to make that the default calling
convention with /Gv. Now, we can't just ignore __stdcall for x64, we
have to treat it as an explicit __cdecl annotation.
Fixes PR42531
Added:
cfe/trunk/test/CodeGen/calling-conv-ignored.c
Modified:
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=365579&r1=365578&r2=365579&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Jul 9 16:17:43 2019
@@ -4655,10 +4655,22 @@ bool Sema::CheckCallingConvAttr(const Pa
} else {
A = TI.checkCallingConvention(CC);
}
- if (A != TargetInfo::CCCR_OK) {
- if (A == TargetInfo::CCCR_Warning)
- Diag(Attrs.getLoc(), diag::warn_cconv_ignored)
- << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
+
+ switch (A) {
+ case TargetInfo::CCCR_OK:
+ break;
+
+ case TargetInfo::CCCR_Ignore:
+ // Treat an ignored convention as if it was an explicit C calling convention
+ // attribute. For example, __stdcall on Win x64 functions as __cdecl, so
+ // that command line flags that change the default convention to
+ // __vectorcall don't affect declarations marked __stdcall.
+ CC = CC_C;
+ break;
+
+ case TargetInfo::CCCR_Warning: {
+ Diag(Attrs.getLoc(), diag::warn_cconv_ignored)
+ << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
// This convention is not valid for the target. Use the default function or
// method calling convention.
@@ -4668,6 +4680,8 @@ bool Sema::CheckCallingConvAttr(const Pa
IsVariadic = FD->isVariadic();
}
CC = Context.getDefaultCallingConvention(IsVariadic, IsCXXMethod);
+ break;
+ }
}
Attrs.setProcessingCache((unsigned) CC);
Added: cfe/trunk/test/CodeGen/calling-conv-ignored.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/calling-conv-ignored.c?rev=365579&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/calling-conv-ignored.c (added)
+++ cfe/trunk/test/CodeGen/calling-conv-ignored.c Tue Jul 9 16:17:43 2019
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -o - %s | FileCheck %s --check-prefix=X86
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -o - %s | FileCheck %s --check-prefix=X64
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -o - %s -fdefault-calling-conv=vectorcall | FileCheck %s --check-prefix=X86-VEC
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -o - %s -fdefault-calling-conv=vectorcall | FileCheck %s --check-prefix=X64-VEC
+
+void foo_default(const char *lpString1, const char *lpString2);
+void __stdcall foo_std(const char *lpString1, const char *lpString2);
+void __fastcall foo_fast(const char *lpString1, const char *lpString2);
+void __vectorcall foo_vector(const char *lpString1, const char *lpString2);
+
+void __cdecl bar() {
+ foo_default(0, 0);
+ foo_std(0, 0);
+ foo_fast(0, 0);
+ foo_vector(0, 0);
+}
+
+// X86-LABEL: define dso_local void @bar()
+// X86: call void @foo_default(i8* null, i8* null)
+// X86: call x86_stdcallcc void @"\01_foo_std at 8"(i8* null, i8* null)
+// X86: call x86_fastcallcc void @"\01 at foo_fast@8"(i8* inreg null, i8* inreg null)
+// X86: call x86_vectorcallcc void @"\01foo_vector@@8"(i8* inreg null, i8* inreg null)
+// X86: ret void
+
+// X64-LABEL: define dso_local void @bar()
+// X64: call void @foo_default(i8* null, i8* null)
+// X64: call void @foo_std(i8* null, i8* null)
+// X64: call void @foo_fast(i8* null, i8* null)
+// X64: call x86_vectorcallcc void @"\01foo_vector@@16"(i8* null, i8* null)
+// X64: ret void
+
+// X86-VEC-LABEL: define dso_local void @bar()
+// X86-VEC: call x86_vectorcallcc void @"\01foo_default@@8"(i8* inreg null, i8* inreg null)
+// X86-VEC: call x86_stdcallcc void @"\01_foo_std at 8"(i8* null, i8* null)
+// X86-VEC: call x86_fastcallcc void @"\01 at foo_fast@8"(i8* inreg null, i8* inreg null)
+// X86-VEC: call x86_vectorcallcc void @"\01foo_vector@@8"(i8* inreg null, i8* inreg null)
+// X86-VEC: ret void
+
+// X64-VEC-LABEL: define dso_local void @bar()
+// X64-VEC: call x86_vectorcallcc void @"\01foo_default@@16"(i8* null, i8* null)
+// X64-VEC: call void @foo_std(i8* null, i8* null)
+// X64-VEC: call void @foo_fast(i8* null, i8* null)
+// X64-VEC: call x86_vectorcallcc void @"\01foo_vector@@16"(i8* null, i8* null)
+// X64-VEC: ret void
+
More information about the cfe-commits
mailing list