Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit af04c0d

Browse files
committed
some more argument checking cleanup
1 parent 550d217 commit af04c0d

File tree

12 files changed

+77
-70
lines changed

12 files changed

+77
-70
lines changed

src/tools/miri/src/helpers.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -999,12 +999,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
999999
&'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>,
10001000
{
10011001
self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?;
1002+
10021003
if abi.c_variadic {
10031004
throw_ub_format!(
10041005
"calling a non-variadic function with a variadic caller-side signature"
10051006
);
10061007
}
1007-
check_arg_count(args)
1008+
if let Ok(ops) = args.try_into() {
1009+
return interp_ok(ops);
1010+
}
1011+
throw_ub_format!(
1012+
"incorrect number of arguments for `{link_name}`: got {}, expected {}",
1013+
args.len(),
1014+
N
1015+
)
10081016
}
10091017

10101018
/// Check shim for variadic function.
@@ -1020,6 +1028,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
10201028
&'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>,
10211029
{
10221030
self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?;
1031+
10231032
if !abi.c_variadic {
10241033
throw_ub_format!(
10251034
"calling a variadic function with a non-variadic caller-side signature"
@@ -1219,7 +1228,7 @@ impl<'tcx> MiriMachine<'tcx> {
12191228
}
12201229

12211230
/// Check that the number of args is what we expect.
1222-
pub fn check_arg_count<'a, 'tcx, const N: usize>(
1231+
pub fn check_intrinsic_arg_count<'a, 'tcx, const N: usize>(
12231232
args: &'a [OpTy<'tcx>],
12241233
) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]>
12251234
where
@@ -1228,7 +1237,11 @@ where
12281237
if let Ok(ops) = args.try_into() {
12291238
return interp_ok(ops);
12301239
}
1231-
throw_ub_format!("incorrect number of arguments: got {}, expected {}", args.len(), N)
1240+
throw_ub_format!(
1241+
"incorrect number of arguments for intrinsic: got {}, expected {}",
1242+
args.len(),
1243+
N
1244+
)
12321245
}
12331246

12341247
/// Check that the number of varargs is at least the minimum what we expect.

src/tools/miri/src/intrinsics/atomic.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_middle::mir::BinOp;
22
use rustc_middle::{mir, ty};
33

4-
use self::helpers::check_arg_count;
4+
use self::helpers::check_intrinsic_arg_count;
55
use crate::*;
66

77
pub enum AtomicOp {
@@ -131,7 +131,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
131131
) -> InterpResult<'tcx> {
132132
let this = self.eval_context_mut();
133133

134-
let [place] = check_arg_count(args)?;
134+
let [place] = check_intrinsic_arg_count(args)?;
135135
let place = this.deref_pointer(place)?;
136136

137137
// Perform atomic load.
@@ -144,7 +144,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
144144
fn atomic_store(&mut self, args: &[OpTy<'tcx>], atomic: AtomicWriteOrd) -> InterpResult<'tcx> {
145145
let this = self.eval_context_mut();
146146

147-
let [place, val] = check_arg_count(args)?;
147+
let [place, val] = check_intrinsic_arg_count(args)?;
148148
let place = this.deref_pointer(place)?;
149149

150150
// Perform regular load.
@@ -159,7 +159,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
159159
args: &[OpTy<'tcx>],
160160
atomic: AtomicFenceOrd,
161161
) -> InterpResult<'tcx> {
162-
let [] = check_arg_count(args)?;
162+
let [] = check_intrinsic_arg_count(args)?;
163163
let _ = atomic;
164164
//FIXME: compiler fences are currently ignored
165165
interp_ok(())
@@ -171,7 +171,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
171171
atomic: AtomicFenceOrd,
172172
) -> InterpResult<'tcx> {
173173
let this = self.eval_context_mut();
174-
let [] = check_arg_count(args)?;
174+
let [] = check_intrinsic_arg_count(args)?;
175175
this.atomic_fence(atomic)?;
176176
interp_ok(())
177177
}
@@ -185,7 +185,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
185185
) -> InterpResult<'tcx> {
186186
let this = self.eval_context_mut();
187187

188-
let [place, rhs] = check_arg_count(args)?;
188+
let [place, rhs] = check_intrinsic_arg_count(args)?;
189189
let place = this.deref_pointer(place)?;
190190
let rhs = this.read_immediate(rhs)?;
191191

@@ -226,7 +226,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
226226
) -> InterpResult<'tcx> {
227227
let this = self.eval_context_mut();
228228

229-
let [place, new] = check_arg_count(args)?;
229+
let [place, new] = check_intrinsic_arg_count(args)?;
230230
let place = this.deref_pointer(place)?;
231231
let new = this.read_scalar(new)?;
232232

@@ -245,7 +245,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
245245
) -> InterpResult<'tcx> {
246246
let this = self.eval_context_mut();
247247

248-
let [place, expect_old, new] = check_arg_count(args)?;
248+
let [place, expect_old, new] = check_intrinsic_arg_count(args)?;
249249
let place = this.deref_pointer(place)?;
250250
let expect_old = this.read_immediate(expect_old)?; // read as immediate for the sake of `binary_op()`
251251
let new = this.read_scalar(new)?;

src/tools/miri/src/intrinsics/mod.rs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::ty::{self, FloatTy};
1111
use rustc_span::{Symbol, sym};
1212

1313
use self::atomic::EvalContextExt as _;
14-
use self::helpers::{ToHost, ToSoft, check_arg_count};
14+
use self::helpers::{ToHost, ToSoft, check_intrinsic_arg_count};
1515
use self::simd::EvalContextExt as _;
1616
use crate::*;
1717

@@ -104,24 +104,24 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
104104

105105
// Raw memory accesses
106106
"volatile_load" => {
107-
let [place] = check_arg_count(args)?;
107+
let [place] = check_intrinsic_arg_count(args)?;
108108
let place = this.deref_pointer(place)?;
109109
this.copy_op(&place, dest)?;
110110
}
111111
"volatile_store" => {
112-
let [place, dest] = check_arg_count(args)?;
112+
let [place, dest] = check_intrinsic_arg_count(args)?;
113113
let place = this.deref_pointer(place)?;
114114
this.copy_op(dest, &place)?;
115115
}
116116

117117
"volatile_set_memory" => {
118-
let [ptr, val_byte, count] = check_arg_count(args)?;
118+
let [ptr, val_byte, count] = check_intrinsic_arg_count(args)?;
119119
this.write_bytes_intrinsic(ptr, val_byte, count, "volatile_set_memory")?;
120120
}
121121

122122
// Memory model / provenance manipulation
123123
"ptr_mask" => {
124-
let [ptr, mask] = check_arg_count(args)?;
124+
let [ptr, mask] = check_intrinsic_arg_count(args)?;
125125

126126
let ptr = this.read_pointer(ptr)?;
127127
let mask = this.read_target_usize(mask)?;
@@ -137,7 +137,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
137137
// ```
138138
// Would not be considered UB, or the other way around (`is_val_statically_known(0)`).
139139
"is_val_statically_known" => {
140-
let [_arg] = check_arg_count(args)?;
140+
let [_arg] = check_intrinsic_arg_count(args)?;
141141
// FIXME: should we check for validity here? It's tricky because we do not have a
142142
// place. Codegen does not seem to set any attributes like `noundef` for intrinsic
143143
// calls, so we don't *have* to do anything.
@@ -146,7 +146,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
146146
}
147147

148148
"floorf16" | "ceilf16" | "truncf16" | "roundf16" | "rintf16" => {
149-
let [f] = check_arg_count(args)?;
149+
let [f] = check_intrinsic_arg_count(args)?;
150150
let f = this.read_scalar(f)?.to_f16()?;
151151
let mode = match intrinsic_name {
152152
"floorf16" => Round::TowardNegative,
@@ -161,7 +161,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
161161
this.write_scalar(res, dest)?;
162162
}
163163
"floorf32" | "ceilf32" | "truncf32" | "roundf32" | "rintf32" => {
164-
let [f] = check_arg_count(args)?;
164+
let [f] = check_intrinsic_arg_count(args)?;
165165
let f = this.read_scalar(f)?.to_f32()?;
166166
let mode = match intrinsic_name {
167167
"floorf32" => Round::TowardNegative,
@@ -176,7 +176,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
176176
this.write_scalar(res, dest)?;
177177
}
178178
"floorf64" | "ceilf64" | "truncf64" | "roundf64" | "rintf64" => {
179-
let [f] = check_arg_count(args)?;
179+
let [f] = check_intrinsic_arg_count(args)?;
180180
let f = this.read_scalar(f)?.to_f64()?;
181181
let mode = match intrinsic_name {
182182
"floorf64" => Round::TowardNegative,
@@ -191,7 +191,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
191191
this.write_scalar(res, dest)?;
192192
}
193193
"floorf128" | "ceilf128" | "truncf128" | "roundf128" | "rintf128" => {
194-
let [f] = check_arg_count(args)?;
194+
let [f] = check_intrinsic_arg_count(args)?;
195195
let f = this.read_scalar(f)?.to_f128()?;
196196
let mode = match intrinsic_name {
197197
"floorf128" => Round::TowardNegative,
@@ -216,7 +216,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
216216
| "log10f32"
217217
| "log2f32"
218218
=> {
219-
let [f] = check_arg_count(args)?;
219+
let [f] = check_intrinsic_arg_count(args)?;
220220
let f = this.read_scalar(f)?.to_f32()?;
221221
// Using host floats except for sqrt (but it's fine, these operations do not have
222222
// guaranteed precision).
@@ -244,7 +244,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
244244
| "log10f64"
245245
| "log2f64"
246246
=> {
247-
let [f] = check_arg_count(args)?;
247+
let [f] = check_intrinsic_arg_count(args)?;
248248
let f = this.read_scalar(f)?.to_f64()?;
249249
// Using host floats except for sqrt (but it's fine, these operations do not have
250250
// guaranteed precision).
@@ -264,7 +264,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
264264
}
265265

266266
"fmaf32" => {
267-
let [a, b, c] = check_arg_count(args)?;
267+
let [a, b, c] = check_intrinsic_arg_count(args)?;
268268
let a = this.read_scalar(a)?.to_f32()?;
269269
let b = this.read_scalar(b)?.to_f32()?;
270270
let c = this.read_scalar(c)?.to_f32()?;
@@ -274,7 +274,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
274274
this.write_scalar(res, dest)?;
275275
}
276276
"fmaf64" => {
277-
let [a, b, c] = check_arg_count(args)?;
277+
let [a, b, c] = check_intrinsic_arg_count(args)?;
278278
let a = this.read_scalar(a)?.to_f64()?;
279279
let b = this.read_scalar(b)?.to_f64()?;
280280
let c = this.read_scalar(c)?.to_f64()?;
@@ -285,7 +285,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
285285
}
286286

287287
"fmuladdf32" => {
288-
let [a, b, c] = check_arg_count(args)?;
288+
let [a, b, c] = check_intrinsic_arg_count(args)?;
289289
let a = this.read_scalar(a)?.to_f32()?;
290290
let b = this.read_scalar(b)?.to_f32()?;
291291
let c = this.read_scalar(c)?.to_f32()?;
@@ -300,7 +300,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
300300
this.write_scalar(res, dest)?;
301301
}
302302
"fmuladdf64" => {
303-
let [a, b, c] = check_arg_count(args)?;
303+
let [a, b, c] = check_intrinsic_arg_count(args)?;
304304
let a = this.read_scalar(a)?.to_f64()?;
305305
let b = this.read_scalar(b)?.to_f64()?;
306306
let c = this.read_scalar(c)?.to_f64()?;
@@ -316,7 +316,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
316316
}
317317

318318
"powf32" => {
319-
let [f1, f2] = check_arg_count(args)?;
319+
let [f1, f2] = check_intrinsic_arg_count(args)?;
320320
let f1 = this.read_scalar(f1)?.to_f32()?;
321321
let f2 = this.read_scalar(f2)?.to_f32()?;
322322
// Using host floats (but it's fine, this operation does not have guaranteed precision).
@@ -325,7 +325,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
325325
this.write_scalar(res, dest)?;
326326
}
327327
"powf64" => {
328-
let [f1, f2] = check_arg_count(args)?;
328+
let [f1, f2] = check_intrinsic_arg_count(args)?;
329329
let f1 = this.read_scalar(f1)?.to_f64()?;
330330
let f2 = this.read_scalar(f2)?.to_f64()?;
331331
// Using host floats (but it's fine, this operation does not have guaranteed precision).
@@ -335,7 +335,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
335335
}
336336

337337
"powif32" => {
338-
let [f, i] = check_arg_count(args)?;
338+
let [f, i] = check_intrinsic_arg_count(args)?;
339339
let f = this.read_scalar(f)?.to_f32()?;
340340
let i = this.read_scalar(i)?.to_i32()?;
341341
// Using host floats (but it's fine, this operation does not have guaranteed precision).
@@ -344,7 +344,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
344344
this.write_scalar(res, dest)?;
345345
}
346346
"powif64" => {
347-
let [f, i] = check_arg_count(args)?;
347+
let [f, i] = check_intrinsic_arg_count(args)?;
348348
let f = this.read_scalar(f)?.to_f64()?;
349349
let i = this.read_scalar(i)?.to_i32()?;
350350
// Using host floats (but it's fine, this operation does not have guaranteed precision).
@@ -360,7 +360,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
360360
| "fdiv_algebraic"
361361
| "frem_algebraic"
362362
=> {
363-
let [a, b] = check_arg_count(args)?;
363+
let [a, b] = check_intrinsic_arg_count(args)?;
364364
let a = this.read_immediate(a)?;
365365
let b = this.read_immediate(b)?;
366366
let op = match intrinsic_name {
@@ -383,7 +383,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
383383
| "fdiv_fast"
384384
| "frem_fast"
385385
=> {
386-
let [a, b] = check_arg_count(args)?;
386+
let [a, b] = check_intrinsic_arg_count(args)?;
387387
let a = this.read_immediate(a)?;
388388
let b = this.read_immediate(b)?;
389389
let op = match intrinsic_name {
@@ -427,7 +427,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
427427
}
428428

429429
"float_to_int_unchecked" => {
430-
let [val] = check_arg_count(args)?;
430+
let [val] = check_intrinsic_arg_count(args)?;
431431
let val = this.read_immediate(val)?;
432432

433433
let res = this
@@ -444,7 +444,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
444444

445445
// Other
446446
"breakpoint" => {
447-
let [] = check_arg_count(args)?;
447+
let [] = check_intrinsic_arg_count(args)?;
448448
// normally this would raise a SIGTRAP, which aborts if no debugger is connected
449449
throw_machine_stop!(TerminationInfo::Abort(format!("trace/breakpoint trap")))
450450
}

0 commit comments

Comments
 (0)