[clang] d8b8f54 - [Reland] "Do not apply calling conventions to MSVC entry points"

Elizabeth Andrews via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 18 04:41:06 PDT 2021


Author: Elizabeth Andrews
Date: 2021-03-18T04:26:47-07:00
New Revision: d8b8f544d9de30cd14584094596090d3f9992345

URL: https://github.com/llvm/llvm-project/commit/d8b8f544d9de30cd14584094596090d3f9992345
DIFF: https://github.com/llvm/llvm-project/commit/d8b8f544d9de30cd14584094596090d3f9992345.diff

LOG: [Reland] "Do not apply calling conventions to MSVC entry points"

This patch is a second attempt at fixing a link error for MSVC
entry points when calling conventions are specified using a flag.

Calling conventions specified using flags should not be applied to MSVC
entry points. The default calling convention is set in this case. The
default calling convention for MSVC entry points main and wmain is cdecl.
For WinMain, wWinMain and DllMain, the default calling convention is
stdcall on 32 bit Windows.

Explicitly specified calling conventions are applied to MSVC entry points.

For MinGW, the default calling convention for all MSVC entry points is
cdecl.

First attempt: 4cff1b40dacf6
Revert of first attempt: bebfc3b92d5e8

Differential Revision: https://reviews.llvm.org/D97941

Added: 
    

Modified: 
    clang/lib/Sema/SemaDecl.cpp
    clang/test/CodeGenCXX/default_calling_conv.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index b962bd965223..76e3ee965777 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11173,6 +11173,25 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
   }
 }
 
+static bool isDefaultStdCall(FunctionDecl *FD, Sema &S) {
+
+  // Default calling convention for main and wmain is __cdecl
+  if (FD->getName() == "main" || FD->getName() == "wmain")
+    return false;
+
+  // Default calling convention for MinGW is __cdecl
+  const llvm::Triple &T = S.Context.getTargetInfo().getTriple();
+  if (T.isWindowsGNUEnvironment())
+    return false;
+
+  // Default calling convention for WinMain, wWinMain and DllMain
+  // is __stdcall on 32 bit Windows
+  if (T.isOSWindows() && T.getArch() == llvm::Triple::x86)
+    return true;
+
+  return false;
+}
+
 void Sema::CheckMSVCRTEntryPoint(FunctionDecl *FD) {
   QualType T = FD->getType();
   assert(T->isFunctionType() && "function decl is not of function type");
@@ -11187,6 +11206,21 @@ void Sema::CheckMSVCRTEntryPoint(FunctionDecl *FD) {
     if (FD->getName() != "DllMain")
       FD->setHasImplicitReturnZero(true);
 
+  // Explicity specified calling conventions are applied to MSVC entry points
+  if (!hasExplicitCallingConv(T)) {
+    if (isDefaultStdCall(FD, *this)) {
+      if (FT->getCallConv() != CC_X86StdCall) {
+        FT = Context.adjustFunctionType(
+            FT, FT->getExtInfo().withCallingConv(CC_X86StdCall));
+        FD->setType(QualType(FT, 0));
+      }
+    } else if (FT->getCallConv() != CC_C) {
+      FT = Context.adjustFunctionType(FT,
+                                      FT->getExtInfo().withCallingConv(CC_C));
+      FD->setType(QualType(FT, 0));
+    }
+  }
+
   if (!FD->isInvalidDecl() && FD->getDescribedFunctionTemplate()) {
     Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD;
     FD->setInvalidDecl();

diff  --git a/clang/test/CodeGenCXX/default_calling_conv.cpp b/clang/test/CodeGenCXX/default_calling_conv.cpp
index e3d7ac429a60..83d1200e0ab1 100644
--- a/clang/test/CodeGenCXX/default_calling_conv.cpp
+++ b/clang/test/CodeGenCXX/default_calling_conv.cpp
@@ -4,6 +4,9 @@
 // RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
 // RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL
 // RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=regcall -emit-llvm -o - %s | FileCheck %s --check-prefix=REGCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i686-pc-win32 -fdefault-calling-conv=vectorcall -emit-llvm -o - %s -DWINDOWS | FileCheck %s --check-prefix=WIN32
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fdefault-calling-conv=vectorcall -emit-llvm -o - %s -DWINDOWS | FileCheck %s --check-prefix=WIN64
+// RUN: %clang_cc1 -triple i686-pc-win32 -emit-llvm -o - %s -DEXPLICITCC | FileCheck %s --check-prefix=EXPLICITCC
 
 // CDECL: define{{.*}} void @_Z5test1v
 // FASTCALL: define{{.*}} x86_fastcallcc void @_Z5test1v
@@ -50,3 +53,45 @@ void test() {
 int main() {
   return 1;
 }
+
+#ifdef WINDOWS
+// WIN32: define dso_local i32 @wmain
+// WIN64: define dso_local i32 @wmain
+int wmain() {
+  return 1;
+}
+// WIN32: define dso_local x86_stdcallcc i32 @WinMain
+// WIN64: define dso_local i32 @WinMain
+int WinMain() {
+  return 1;
+}
+// WIN32: define dso_local x86_stdcallcc i32 @wWinMain
+// WIN64: define dso_local i32 @wWinMain
+int wWinMain() {
+  return 1;
+}
+// WIN32: define dso_local x86_stdcallcc i32 @DllMain
+// WIN64: define dso_local i32 @DllMain
+int DllMain() {
+  return 1;
+}
+#endif // Windows
+
+#ifdef EXPLICITCC
+// EXPLICITCC: define dso_local x86_fastcallcc i32 @wmain
+int __fastcall wmain() {
+  return 1;
+}
+// EXPLICITCC: define dso_local x86_fastcallcc i32 @WinMain
+int __fastcall WinMain() {
+  return 1;
+}
+// EXPLICITCC: define dso_local x86_fastcallcc i32 @wWinMain
+int __fastcall wWinMain() {
+  return 1;
+}
+// EXPLICITCC: define dso_local x86_fastcallcc i32 @DllMain
+int __fastcall DllMain() {
+  return 1;
+}
+#endif // ExplicitCC


        


More information about the cfe-commits mailing list