Skip to content

[clang] Handle CC attrs for UEFI #138935

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/X86.h
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,7 @@ class LLVM_LIBRARY_VISIBILITY UEFIX86_64TargetInfo
switch (CC) {
case CC_C:
case CC_Win64:
case CC_X86_64SysV:
return CCCR_OK;
default:
return CCCR_Warning;
Expand Down
13 changes: 8 additions & 5 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP) {
}

static CallingConv getCallingConventionForDecl(const ObjCMethodDecl *D,
bool IsWindows) {
bool IsTargetDefaultMSABI) {
// Set the appropriate calling convention for the Function.
if (D->hasAttr<StdCallAttr>())
return CC_X86StdCall;
Expand Down Expand Up @@ -290,10 +290,10 @@ static CallingConv getCallingConventionForDecl(const ObjCMethodDecl *D,
return CC_IntelOclBicc;

if (D->hasAttr<MSABIAttr>())
return IsWindows ? CC_C : CC_Win64;
return IsTargetDefaultMSABI ? CC_C : CC_Win64;

if (D->hasAttr<SysVABIAttr>())
return IsWindows ? CC_X86_64SysV : CC_C;
return IsTargetDefaultMSABI ? CC_X86_64SysV : CC_C;

if (D->hasAttr<PreserveMostAttr>())
return CC_PreserveMost;
Expand Down Expand Up @@ -581,8 +581,11 @@ CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
}

FunctionType::ExtInfo einfo;
bool IsWindows = getContext().getTargetInfo().getTriple().isOSWindows();
einfo = einfo.withCallingConv(getCallingConventionForDecl(MD, IsWindows));
bool IsTargetDefaultMSABI =
getContext().getTargetInfo().getTriple().isOSWindows() ||
getContext().getTargetInfo().getTriple().isUEFI();
einfo = einfo.withCallingConv(
getCallingConventionForDecl(MD, IsTargetDefaultMSABI));

if (getContext().getLangOpts().ObjCAutoRefCount &&
MD->hasAttr<NSReturnsRetainedAttr>())
Expand Down
10 changes: 5 additions & 5 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4868,27 +4868,27 @@ static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn) {
bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
TT.getArch() == llvm::Triple::aarch64_32);
bool IsWindows = TT.isOSWindows();
bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
if (IsX64 || IsAArch64) {
CallingConv CC = CC_C;
if (const FunctionDecl *FD = S.getCurFunctionDecl())
CC = FD->getType()->castAs<FunctionType>()->getCallConv();
if (IsMSVAStart) {
// Don't allow this in System V ABI functions.
if (CC == CC_X86_64SysV || (!IsWindows && CC != CC_Win64))
if (CC == CC_X86_64SysV || (!IsWindowsOrUEFI && CC != CC_Win64))
return S.Diag(Fn->getBeginLoc(),
diag::err_ms_va_start_used_in_sysv_function);
} else {
// On x86-64/AArch64 Unix, don't allow this in Win64 ABI functions.
// On x64 Windows, don't allow this in System V ABI functions.
// (Yes, that means there's no corresponding way to support variadic
// System V ABI functions on Windows.)
if ((IsWindows && CC == CC_X86_64SysV) ||
(!IsWindows && CC == CC_Win64))
if ((IsWindowsOrUEFI && CC == CC_X86_64SysV) ||
(!IsWindowsOrUEFI && CC == CC_Win64))
return S.Diag(Fn->getBeginLoc(),
diag::err_va_start_used_in_wrong_abi_function)
<< !IsWindows;
<< !IsWindowsOrUEFI;
}
return false;
}
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5397,6 +5397,9 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
}
}

bool IsTargetDefaultMSABI =
Context.getTargetInfo().getTriple().isOSWindows() ||
Context.getTargetInfo().getTriple().isUEFI();
// TODO: diagnose uses of these conventions on the wrong target.
switch (Attrs.getKind()) {
case ParsedAttr::AT_CDecl:
Expand Down Expand Up @@ -5436,12 +5439,10 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
CC = CC_X86RegCall;
break;
case ParsedAttr::AT_MSABI:
CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
CC_Win64;
CC = IsTargetDefaultMSABI ? CC_C : CC_Win64;
break;
case ParsedAttr::AT_SysVABI:
CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
CC_C;
CC = IsTargetDefaultMSABI ? CC_X86_64SysV : CC_C;
break;
case ParsedAttr::AT_Pcs: {
StringRef StrRef;
Expand Down
1 change: 1 addition & 0 deletions clang/test/CodeGen/ms_abi.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-unknown-freebsd10.0 -emit-llvm < %s | FileCheck -check-prefix=FREEBSD %s
// RUN: %clang_cc1 -triple x86_64-pc-win32 -emit-llvm < %s | FileCheck -check-prefix=WIN64 %s
// RUN: %clang_cc1 -triple x86_64-uefi -emit-llvm < %s | FileCheck -check-prefix=WIN64 %s

struct foo {
int x;
Expand Down
2 changes: 2 additions & 0 deletions clang/test/CodeGen/sysv_abi.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// RUN: %clang_cc1 -triple x86_64-pc-win32 -emit-llvm -target-cpu skylake-avx512 < %s | FileCheck %s --check-prefixes=CHECK,AVX
// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -target-cpu skylake-avx512 < %s | FileCheck %s --check-prefixes=CHECK,AVX
// RUN: %clang_cc1 -triple x86_64-uefi -emit-llvm -target-cpu skylake-avx512 < %s | FileCheck %s --check-prefixes=CHECK,AVX
// RUN: %clang_cc1 -triple x86_64-pc-win32 -emit-llvm < %s | FileCheck %s --check-prefixes=CHECK,NOAVX
// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm < %s | FileCheck %s --check-prefixes=CHECK,NOAVX
// RUN: %clang_cc1 -triple x86_64-uefi -emit-llvm < %s | FileCheck %s --check-prefixes=CHECK,NOAVX

#define SYSV_CC __attribute__((sysv_abi))

Expand Down
1 change: 1 addition & 0 deletions clang/test/Sema/callingconv-ms_abi.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-pc-win32 %s
// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-uefi %s

void __attribute__((ms_abi)) foo(void);
void (*pfoo)(void) = foo;
Expand Down
1 change: 1 addition & 0 deletions clang/test/Sema/varargs-win64.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-pc-win32
// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-uefi

void __attribute__((sysv_abi)) foo(int a, ...) {
__builtin_va_list ap;
Expand Down