Skip to content

Commit e591b83

Browse files
committed
UB if f*_fast intrinsic called with nonfinite value
1 parent 0e30385 commit e591b83

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

src/shims/intrinsics.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,36 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
173173
"frem_fast" => mir::BinOp::Rem,
174174
_ => bug!(),
175175
};
176+
let a_valid = match a.layout.ty.kind() {
177+
ty::Float(FloatTy::F32) => a.to_scalar()?.to_f32()?.is_finite(),
178+
ty::Float(FloatTy::F64) => a.to_scalar()?.to_f64()?.is_finite(),
179+
_ => bug!(
180+
"`{}` called with non-float input type {:?}",
181+
intrinsic_name,
182+
a.layout.ty
183+
),
184+
};
185+
if !a_valid {
186+
throw_ub_format!(
187+
"`{}` intrinsic called with non-finite value as first parameter",
188+
intrinsic_name,
189+
);
190+
}
191+
let b_valid = match b.layout.ty.kind() {
192+
ty::Float(FloatTy::F32) => b.to_scalar()?.to_f32()?.is_finite(),
193+
ty::Float(FloatTy::F64) => b.to_scalar()?.to_f64()?.is_finite(),
194+
_ => bug!(
195+
"`{}` called with non-float input type {:?}",
196+
intrinsic_name,
197+
b.layout.ty
198+
),
199+
};
200+
if !b_valid {
201+
throw_ub_format!(
202+
"`{}` intrinsic called with non-finite value as second parameter",
203+
intrinsic_name,
204+
);
205+
}
176206
this.binop_ignore_overflow(op, &a, &b, dest)?;
177207
}
178208

tests/compile-fail/fast_math_both.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![feature(core_intrinsics)]
2+
3+
fn main() {
4+
unsafe {
5+
let _x: f32 = core::intrinsics::frem_fast(f32::NAN, 3.2); //~ ERROR `frem_fast` intrinsic called with non-finite value as first parameter
6+
}
7+
}

tests/compile-fail/fast_math_first.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![feature(core_intrinsics)]
2+
3+
fn main() {
4+
unsafe {
5+
let _x: f32 = core::intrinsics::fsub_fast(f32::NAN, f32::NAN); //~ ERROR `fsub_fast` intrinsic called with non-finite value as first parameter
6+
}
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![feature(core_intrinsics)]
2+
3+
fn main() {
4+
unsafe {
5+
let _x: f32 = core::intrinsics::fmul_fast(3.4f32, f32::NAN); //~ ERROR `fmul_fast` intrinsic called with non-finite value as second parameter
6+
}
7+
}

0 commit comments

Comments
 (0)