mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
refactor llvm va_arg intrinsic validation logic
This commit is contained in:
@@ -3,7 +3,8 @@
|
||||
use std::{assert_matches, iter, ptr};
|
||||
|
||||
use rustc_abi::{
|
||||
Align, BackendRepr, Float, HasDataLayout, NumScalableVectors, Primitive, Size, WrappingRange,
|
||||
Align, BackendRepr, Float, HasDataLayout, Integer, NumScalableVectors, Primitive, Size,
|
||||
WrappingRange,
|
||||
};
|
||||
use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh};
|
||||
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
|
||||
@@ -288,10 +289,17 @@ fn codegen_intrinsic_call(
|
||||
bug!("the va_arg intrinsic does not support non-scalar types")
|
||||
};
|
||||
|
||||
// We reject types that would never be passed as varargs in C because
|
||||
// they get promoted to a larger type, specifically integers smaller than
|
||||
// c_int and float type smaller than c_double.
|
||||
match scalar.primitive() {
|
||||
Primitive::Pointer(_) => {
|
||||
// Pointers are always OK.
|
||||
emit_va_arg(self, args[0], result.layout.ty)
|
||||
}
|
||||
Primitive::Int(Integer::I128, _) => {
|
||||
// FIXME: maybe we should support these? At least on 32-bit powerpc
|
||||
// the logic in LLVM does not handle i128 correctly though.
|
||||
bug!("the va_arg intrinsic does not support `i128`/`u128`")
|
||||
}
|
||||
Primitive::Int(..) => {
|
||||
let int_width = self.cx().size_of(result.layout.ty).bits();
|
||||
@@ -305,27 +313,26 @@ fn codegen_intrinsic_call(
|
||||
target_c_int_width
|
||||
);
|
||||
}
|
||||
emit_va_arg(self, args[0], result.layout.ty)
|
||||
}
|
||||
Primitive::Float(Float::F16) => {
|
||||
bug!("the va_arg intrinsic does not support `f16`")
|
||||
}
|
||||
Primitive::Float(Float::F32) => {
|
||||
if self.cx().sess().target.arch == Arch::Avr {
|
||||
// c_double is actually f32 on avr.
|
||||
emit_va_arg(self, args[0], result.layout.ty)
|
||||
} else {
|
||||
// c_double is actually f32 on avr.
|
||||
if self.cx().sess().target.arch != Arch::Avr {
|
||||
bug!("the va_arg intrinsic does not support `f32` on this target")
|
||||
}
|
||||
}
|
||||
Primitive::Float(Float::F64) => {
|
||||
// 64-bit floats are always OK.
|
||||
emit_va_arg(self, args[0], result.layout.ty)
|
||||
}
|
||||
Primitive::Float(Float::F128) => {
|
||||
// FIXME(f128) figure out whether we should support this.
|
||||
bug!("the va_arg intrinsic does not support `f128`")
|
||||
}
|
||||
}
|
||||
|
||||
emit_va_arg(self, args[0], result.layout.ty)
|
||||
}
|
||||
|
||||
sym::volatile_load | sym::unaligned_volatile_load => {
|
||||
|
||||
Reference in New Issue
Block a user