From: Erich Keane Date: Thu, 23 May 2019 16:05:21 +0000 (+0000) Subject: Ensure builtins use the target default Calling Convention X-Git-Tag: llvmorg-10-init~4783 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=000228183bf17a0f64afccdda35867553c9b75f6;p=platform%2Fupstream%2Fllvm.git Ensure builtins use the target default Calling Convention r355317 changed builtins/allocation functions to use the default calling convention in order to support platforms that use non-cdecl calling conventions by default. However the default calling convention is overridable on Windows 32 bit implementations with some of the /G options. The intent is to permit the user to set the calling convention of normal functions, however it should NOT apply to builtins and C++ allocation functions. This patch ensures that the builtin/allocation functions always use the Target specific Calling Convention, ignoring the user overridden version of said default. llvm-svn: 361507 --- diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 5cb4a82..6856cb6 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2395,7 +2395,8 @@ public: /// Retrieves the default calling convention for the current target. CallingConv getDefaultCallingConvention(bool IsVariadic, - bool IsCXXMethod) const; + bool IsCXXMethod, + bool IsBuiltin = false) const; /// Retrieves the "canonical" template name that refers to a /// given template. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 7174504..c3a0972 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -9627,8 +9627,8 @@ QualType ASTContext::GetBuiltinType(unsigned Id, bool Variadic = (TypeStr[0] == '.'); - FunctionType::ExtInfo EI( - getDefaultCallingConvention(Variadic, /*IsCXXMethod=*/false)); + FunctionType::ExtInfo EI(getDefaultCallingConvention( + Variadic, /*IsCXXMethod=*/false, /*IsBuiltin=*/true)); if (BuiltinInfo.isNoReturn(Id)) EI = EI.withNoReturn(true); @@ -10005,34 +10005,39 @@ void ASTContext::forEachMultiversionedFunctionVersion( } CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic, - bool IsCXXMethod) const { + bool IsCXXMethod, + bool IsBuiltin) const { // Pass through to the C++ ABI object if (IsCXXMethod) return ABI->getDefaultMethodCallConv(IsVariadic); - switch (LangOpts.getDefaultCallingConv()) { - case LangOptions::DCC_None: - break; - case LangOptions::DCC_CDecl: - return CC_C; - case LangOptions::DCC_FastCall: - if (getTargetInfo().hasFeature("sse2") && !IsVariadic) - return CC_X86FastCall; - break; - case LangOptions::DCC_StdCall: - if (!IsVariadic) - return CC_X86StdCall; - break; - case LangOptions::DCC_VectorCall: - // __vectorcall cannot be applied to variadic functions. - if (!IsVariadic) - return CC_X86VectorCall; - break; - case LangOptions::DCC_RegCall: - // __regcall cannot be applied to variadic functions. - if (!IsVariadic) - return CC_X86RegCall; - break; + // Builtins ignore user-specified default calling convention and remain the + // Target's default calling convention. + if (!IsBuiltin) { + switch (LangOpts.getDefaultCallingConv()) { + case LangOptions::DCC_None: + break; + case LangOptions::DCC_CDecl: + return CC_C; + case LangOptions::DCC_FastCall: + if (getTargetInfo().hasFeature("sse2") && !IsVariadic) + return CC_X86FastCall; + break; + case LangOptions::DCC_StdCall: + if (!IsVariadic) + return CC_X86StdCall; + break; + case LangOptions::DCC_VectorCall: + // __vectorcall cannot be applied to variadic functions. + if (!IsVariadic) + return CC_X86VectorCall; + break; + case LangOptions::DCC_RegCall: + // __regcall cannot be applied to variadic functions. + if (!IsVariadic) + return CC_X86RegCall; + break; + } } return Target->getDefaultCallingConv(TargetInfo::CCMT_Unknown); } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 87dc3a9..455a71b 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2816,7 +2816,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, } FunctionProtoType::ExtProtoInfo EPI(Context.getDefaultCallingConvention( - /*IsVariadic=*/false, /*IsCXXMethod=*/false)); + /*IsVariadic=*/false, /*IsCXXMethod=*/false, /*IsBuiltin=*/true)); QualType BadAllocType; bool HasBadAllocExceptionSpec diff --git a/clang/test/CodeGenCXX/builtin-calling-conv.cpp b/clang/test/CodeGenCXX/builtin-calling-conv.cpp index 6fdeca0..f7759e3 100644 --- a/clang/test/CodeGenCXX/builtin-calling-conv.cpp +++ b/clang/test/CodeGenCXX/builtin-calling-conv.cpp @@ -2,6 +2,7 @@ // RUN: %clang_cc1 -triple spir-unknown-unknown -DREDECL -DSPIR -emit-llvm %s -o - | FileCheck %s -check-prefix SPIR // RUN: %clang_cc1 -triple x86_64-linux-pc -emit-llvm %s -o - | FileCheck %s -check-prefix LINUX // RUN: %clang_cc1 -triple spir-unknown-unknown -DSPIR -emit-llvm %s -o - | FileCheck %s -check-prefix SPIR +// RUN: %clang_cc1 -triple i386-windows-pc -fdefault-calling-conv=stdcall -emit-llvm %s -o - | FileCheck %s -check-prefix WIN32 #ifdef REDECL namespace std { @@ -40,3 +41,13 @@ void user() { // SPIR: declare spir_func noalias i8* @_Znwj(i32) // SPIR: declare spir_func float @atan2f(float, float) // SPIR: declare spir_func void @_Z3foov() + +// Note: Windows /G options should not change the platform default calling +// convention of builtins. +// WIN32: define dso_local x86_stdcallcc void @"?user@@YGXXZ"() +// WIN32: call i8* @"??2@YAPAXI@Z" +// WIN32: call float @atan2f +// WIN32: call x86_stdcallcc void @"?foo@@YGXXZ" +// WIN32: declare dso_local noalias i8* @"??2@YAPAXI@Z"( +// WIN32: declare dso_local float @atan2f(float, float) +// WIN32: declare dso_local x86_stdcallcc void @"?foo@@YGXXZ"()