Fix 32-bit overflows in LLVM composite constants

This commit is contained in:
erer1243 2024-03-04 16:17:23 -05:00
parent af69f4c48c
commit 3af28f0b70
4 changed files with 52 additions and 30 deletions

View File

@ -95,11 +95,13 @@ impl<'ll> BackendTypes for CodegenCx<'ll, '_> {
impl<'ll> CodegenCx<'ll, '_> {
pub fn const_array(&self, ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value {
unsafe { llvm::LLVMConstArray(ty, elts.as_ptr(), elts.len() as c_uint) }
let len = u64::try_from(elts.len()).expect("LLVMConstArray2 elements len overflow");
unsafe { llvm::LLVMConstArray2(ty, elts.as_ptr(), len) }
}
pub fn const_vector(&self, elts: &[&'ll Value]) -> &'ll Value {
unsafe { llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint) }
let len = c_uint::try_from(elts.len()).expect("LLVMConstVector elements len overflow");
unsafe { llvm::LLVMConstVector(elts.as_ptr(), len) }
}
pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value {
@ -108,8 +110,8 @@ pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value {
pub fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
unsafe {
assert_eq!(idx as c_uint as u64, idx);
let r = llvm::LLVMGetAggregateElement(v, idx as c_uint).unwrap();
let idx = c_uint::try_from(idx).expect("LLVMGetAggregateElement index overflow");
let r = llvm::LLVMGetAggregateElement(v, idx).unwrap();
debug!("const_get_elt(v={:?}, idx={}, r={:?})", v, idx, r);
@ -329,7 +331,7 @@ pub fn val_ty(v: &Value) -> &Type {
pub fn bytes_in_context<'ll>(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value {
unsafe {
let ptr = bytes.as_ptr() as *const c_char;
llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True)
llvm::LLVMConstStringInContext2(llcx, ptr, bytes.len(), True)
}
}
@ -338,9 +340,8 @@ pub fn struct_in_context<'ll>(
elts: &[&'ll Value],
packed: bool,
) -> &'ll Value {
unsafe {
llvm::LLVMConstStructInContext(llcx, elts.as_ptr(), elts.len() as c_uint, packed as Bool)
}
let len = c_uint::try_from(elts.len()).expect("LLVMConstStructInContext elements len overflow");
unsafe { llvm::LLVMConstStructInContext(llcx, elts.as_ptr(), len, packed as Bool) }
}
#[inline]

View File

@ -936,10 +936,16 @@ pub fn LLVMMDNodeInContext2<'a>(
pub fn LLVMConstReal(RealTy: &Type, N: f64) -> &Value;
// Operations on composite constants
pub fn LLVMConstStringInContext(
pub fn LLVMConstArray2<'a>(
ElementTy: &'a Type,
ConstantVals: *const &'a Value,
Length: u64,
) -> &'a Value;
pub fn LLVMArrayType2(ElementType: &Type, ElementCount: u64) -> &Type;
pub fn LLVMConstStringInContext2(
C: &Context,
Str: *const c_char,
Length: c_uint,
Length: size_t,
DontNullTerminate: Bool,
) -> &Value;
pub fn LLVMConstStructInContext<'a>(
@ -948,14 +954,6 @@ pub fn LLVMConstStructInContext<'a>(
Count: c_uint,
Packed: Bool,
) -> &'a Value;
// FIXME: replace with LLVMConstArray2 when bumped minimal version to llvm-17
// https://github.com/llvm/llvm-project/commit/35276f16e5a2cae0dfb49c0fbf874d4d2f177acc
pub fn LLVMConstArray<'a>(
ElementTy: &'a Type,
ConstantVals: *const &'a Value,
Length: c_uint,
) -> &'a Value;
pub fn LLVMConstVector(ScalarConstantVals: *const &Value, Size: c_uint) -> &Value;
// Constant expressions
@ -1530,9 +1528,6 @@ pub fn LLVMStructSetBody<'a>(
/// See llvm::LLVMTypeKind::getTypeID.
pub fn LLVMRustGetTypeKind(Ty: &Type) -> TypeKind;
// Operations on array, pointer, and vector types (sequence types)
pub fn LLVMRustArrayType(ElementType: &Type, ElementCount: u64) -> &Type;
// Operations on all values
pub fn LLVMRustGlobalAddMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
pub fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool;

View File

@ -233,7 +233,7 @@ fn val_ty(&self, v: &'ll Value) -> &'ll Type {
}
fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type {
unsafe { llvm::LLVMRustArrayType(ty, len) }
unsafe { llvm::LLVMArrayType2(ty, len) }
}
}

View File

@ -10,6 +10,7 @@
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/LLVMRemarkStreamer.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Value.h"
#include "llvm/Remarks/RemarkStreamer.h"
#include "llvm/Remarks/RemarkSerializer.h"
#include "llvm/Remarks/RemarkFormat.h"
@ -1223,14 +1224,6 @@ extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
}
}
// LLVMArrayType function does not support 64-bit ElementCount
// FIXME: replace with LLVMArrayType2 when bumped minimal version to llvm-17
// https://github.com/llvm/llvm-project/commit/35276f16e5a2cae0dfb49c0fbf874d4d2f177acc
extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
uint64_t ElementCount) {
return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
}
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
@ -2114,3 +2107,36 @@ extern "C" bool LLVMRustLLVMHasZlibCompressionForDebugSymbols() {
extern "C" bool LLVMRustLLVMHasZstdCompressionForDebugSymbols() {
return llvm::compression::zstd::isAvailable();
}
// Operations on composite constants.
// These are clones of LLVM api functions that will become available in future releases.
// They can be removed once Rust's minimum supported LLVM version supports them.
// See https://github.com/rust-lang/rust/issues/121868
// See https://llvm.org/doxygen/group__LLVMCCoreValueConstantComposite.html
// FIXME: Remove when Rust's minimum supported LLVM version reaches 19.
// https://github.com/llvm/llvm-project/commit/e1405e4f71c899420ebf8262d5e9745598419df8
#if LLVM_VERSION_LT(19, 0)
extern "C" LLVMValueRef LLVMConstStringInContext2(LLVMContextRef C,
const char *Str,
size_t Length,
bool DontNullTerminate) {
return wrap(ConstantDataArray::getString(*unwrap(C), StringRef(Str, Length), !DontNullTerminate));
}
#endif
// FIXME: Remove when Rust's minimum supported LLVM version reaches 17.
// https://github.com/llvm/llvm-project/commit/35276f16e5a2cae0dfb49c0fbf874d4d2f177acc
#if LLVM_VERSION_LT(17, 0)
extern "C" LLVMValueRef LLVMConstArray2(LLVMTypeRef ElementTy,
LLVMValueRef *ConstantVals,
uint64_t Length) {
ArrayRef<Constant *> V(unwrap<Constant>(ConstantVals, Length), Length);
return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), V));
}
extern "C" LLVMTypeRef LLVMArrayType2(LLVMTypeRef ElementTy,
uint64_t ElementCount) {
return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
}
#endif