forked from OSchip/llvm-project
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
This commit is contained in:
parent
6aebd8394a
commit
000228183b
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"()
|
||||
|
|
Loading…
Reference in New Issue