Skip to content

Commit 95697a8

Browse files
committed
Fix removal of function attributes on ARM
We use a 64bit integer to pass the set of attributes that is to be removed, but the called C function expects a 32bit integer. On most platforms this doesn't cause any problems other than being unable to unset some attributes, but on ARM even the lower 32bit aren't handled correctly because the 64bit value is passed in different registers, so the C function actually sees random garbage. So we need to fix the relevant functions to use 32bit integers instead. Additionally we need an implementation that actually accepts 64bit integers because some attributes can only be unset that way. Fixes #32360
1 parent d322f99 commit 95697a8

File tree

3 files changed

+26
-27
lines changed

3 files changed

+26
-27
lines changed

src/librustc_llvm/lib.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -964,9 +964,10 @@ extern {
964964
pub fn LLVMAddFunctionAttrStringValue(Fn: ValueRef, index: c_uint,
965965
Name: *const c_char,
966966
Value: *const c_char);
967+
pub fn LLVMRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: uint64_t);
967968
pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
968-
pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
969-
pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, val: c_ulonglong);
969+
pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_uint;
970+
pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, val: c_uint);
970971

971972
/* Operations on parameters */
972973
pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
@@ -2184,6 +2185,13 @@ pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) {
21842185
}
21852186
}
21862187

2188+
pub fn RemoveFunctionAttributes(fn_: ValueRef, attr: Attribute) {
2189+
unsafe {
2190+
LLVMRemoveFunctionAttributes(fn_, FunctionIndex as c_uint,
2191+
attr.bits() as uint64_t)
2192+
}
2193+
}
2194+
21872195
/* Memory-managed interface to target data. */
21882196

21892197
pub struct TargetData {

src/librustc_trans/trans/attributes.rs

+6-25
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010
//! Set and unset common attributes on LLVM values.
1111
12-
use libc::{c_uint, c_ulonglong};
12+
use libc::c_uint;
1313
use llvm::{self, ValueRef};
1414
use session::config::NoDebugInfo;
1515
pub use syntax::attr::InlineAttr;
@@ -28,9 +28,7 @@ pub fn inline(val: ValueRef, inline: InlineAttr) {
2828
let attr = llvm::Attribute::InlineHint |
2929
llvm::Attribute::AlwaysInline |
3030
llvm::Attribute::NoInline;
31-
unsafe {
32-
llvm::LLVMRemoveFunctionAttr(val, attr.bits() as c_ulonglong)
33-
}
31+
llvm::RemoveFunctionAttributes(val, attr)
3432
},
3533
};
3634
}
@@ -41,25 +39,15 @@ pub fn emit_uwtable(val: ValueRef, emit: bool) {
4139
if emit {
4240
llvm::SetFunctionAttribute(val, llvm::Attribute::UWTable);
4341
} else {
44-
unsafe {
45-
llvm::LLVMRemoveFunctionAttr(
46-
val,
47-
llvm::Attribute::UWTable.bits() as c_ulonglong,
48-
);
49-
}
42+
llvm::RemoveFunctionAttributes(val, llvm::Attribute::UWTable);
5043
}
5144
}
5245

5346
/// Tell LLVM whether the function can or cannot unwind.
5447
#[inline]
5548
pub fn unwind(val: ValueRef, can_unwind: bool) {
5649
if can_unwind {
57-
unsafe {
58-
llvm::LLVMRemoveFunctionAttr(
59-
val,
60-
llvm::Attribute::NoUnwind.bits() as c_ulonglong,
61-
);
62-
}
50+
llvm::RemoveFunctionAttributes(val, llvm::Attribute::NoUnwind);
6351
} else {
6452
llvm::SetFunctionAttribute(val, llvm::Attribute::NoUnwind);
6553
}
@@ -72,12 +60,7 @@ pub fn set_optimize_for_size(val: ValueRef, optimize: bool) {
7260
if optimize {
7361
llvm::SetFunctionAttribute(val, llvm::Attribute::OptimizeForSize);
7462
} else {
75-
unsafe {
76-
llvm::LLVMRemoveFunctionAttr(
77-
val,
78-
llvm::Attribute::OptimizeForSize.bits() as c_ulonglong,
79-
);
80-
}
63+
llvm::RemoveFunctionAttributes(val, llvm::Attribute::OptimizeForSize);
8164
}
8265
}
8366

@@ -87,9 +70,7 @@ pub fn naked(val: ValueRef, is_naked: bool) {
8770
if is_naked {
8871
llvm::SetFunctionAttribute(val, llvm::Attribute::Naked);
8972
} else {
90-
unsafe {
91-
llvm::LLVMRemoveFunctionAttr(val, llvm::Attribute::Naked.bits() as c_ulonglong);
92-
}
73+
llvm::RemoveFunctionAttributes(val, llvm::Attribute::Naked);
9374
}
9475
}
9576

src/rustllvm/RustWrapper.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,16 @@ extern "C" void LLVMAddFunctionAttrStringValue(LLVMValueRef Fn, unsigned index,
151151
F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
152152
}
153153

154+
extern "C" void LLVMRemoveFunctionAttributes(LLVMValueRef Fn, unsigned index, uint64_t Val) {
155+
Function *A = unwrap<Function>(Fn);
156+
const AttributeSet PAL = A->getAttributes();
157+
AttrBuilder B(Val);
158+
const AttributeSet PALnew =
159+
PAL.removeAttributes(A->getContext(), index,
160+
AttributeSet::get(A->getContext(), index, B));
161+
A->setAttributes(PALnew);
162+
}
163+
154164
extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, unsigned index, const char *Name) {
155165
Function *f = unwrap<Function>(fn);
156166
LLVMContext &C = f->getContext();

0 commit comments

Comments
 (0)