Auto merge of #128761 - matthiaskrgr:rollup-5p1mlqq, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #124944 (On trait bound mismatch, detect multiple crate versions in dep tree) - #125048 (PinCoerceUnsized trait into core) - #128406 (implement BufReader::peek) - #128539 (Forbid unused unsafe in vxworks-specific std modules) - #128687 (interpret: refactor function call handling to be better-abstracted) - #128692 (Add a triagebot mention for `library/Cargo.lock`) - #128710 (Don't ICE when getting an input file name's stem fails) - #128718 (Consider `cfg_attr` checked by `CheckAttrVisitor`) - #128751 (std:🧵 set_name implementation proposal for vxWorks.) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
6696447f78
58 changed files with 2069 additions and 1386 deletions
|
|
@ -256,7 +256,7 @@ pub struct Thread<'tcx> {
|
|||
/// which then forwards it to 'Resume'. However this argument is implicit in MIR,
|
||||
/// so we have to store it out-of-band. When there are multiple active unwinds,
|
||||
/// the innermost one is always caught first, so we can store them as a stack.
|
||||
pub(crate) panic_payloads: Vec<Scalar>,
|
||||
pub(crate) panic_payloads: Vec<ImmTy<'tcx>>,
|
||||
|
||||
/// Last OS error location in memory. It is a 32-bit integer.
|
||||
pub(crate) last_error: Option<MPlaceTy<'tcx>>,
|
||||
|
|
@ -377,10 +377,6 @@ impl VisitProvenance for Frame<'_, Provenance, FrameExtra<'_>> {
|
|||
return_place,
|
||||
locals,
|
||||
extra,
|
||||
body: _,
|
||||
instance: _,
|
||||
return_to_block: _,
|
||||
loc: _,
|
||||
// There are some private fields we cannot access; they contain no tags.
|
||||
..
|
||||
} = self;
|
||||
|
|
@ -952,7 +948,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.call_function(
|
||||
instance,
|
||||
start_abi,
|
||||
&[*func_arg],
|
||||
&[func_arg],
|
||||
Some(&ret_place),
|
||||
StackPopCleanup::Root { cleanup: true },
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -307,7 +307,8 @@ pub fn create_ecx<'tcx>(
|
|||
// First argument is constructed later, because it's skipped if the entry function uses #[start].
|
||||
|
||||
// Second argument (argc): length of `config.args`.
|
||||
let argc = Scalar::from_target_usize(u64::try_from(config.args.len()).unwrap(), &ecx);
|
||||
let argc =
|
||||
ImmTy::from_int(i64::try_from(config.args.len()).unwrap(), ecx.machine.layouts.isize);
|
||||
// Third argument (`argv`): created from `config.args`.
|
||||
let argv = {
|
||||
// Put each argument in memory, collect pointers.
|
||||
|
|
@ -334,13 +335,11 @@ pub fn create_ecx<'tcx>(
|
|||
ecx.write_immediate(arg, &place)?;
|
||||
}
|
||||
ecx.mark_immutable(&argvs_place);
|
||||
// A pointer to that place is the 3rd argument for main.
|
||||
let argv = argvs_place.to_ref(&ecx);
|
||||
// Store `argc` and `argv` for macOS `_NSGetArg{c,v}`.
|
||||
{
|
||||
let argc_place =
|
||||
ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into())?;
|
||||
ecx.write_scalar(argc, &argc_place)?;
|
||||
ecx.write_immediate(*argc, &argc_place)?;
|
||||
ecx.mark_immutable(&argc_place);
|
||||
ecx.machine.argc = Some(argc_place.ptr());
|
||||
|
||||
|
|
@ -348,7 +347,7 @@ pub fn create_ecx<'tcx>(
|
|||
ecx.layout_of(Ty::new_imm_ptr(tcx, tcx.types.unit))?,
|
||||
MiriMemoryKind::Machine.into(),
|
||||
)?;
|
||||
ecx.write_immediate(argv, &argv_place)?;
|
||||
ecx.write_pointer(argvs_place.ptr(), &argv_place)?;
|
||||
ecx.mark_immutable(&argv_place);
|
||||
ecx.machine.argv = Some(argv_place.ptr());
|
||||
}
|
||||
|
|
@ -369,7 +368,7 @@ pub fn create_ecx<'tcx>(
|
|||
}
|
||||
ecx.mark_immutable(&cmd_place);
|
||||
}
|
||||
argv
|
||||
ecx.mplace_to_ref(&argvs_place)?
|
||||
};
|
||||
|
||||
// Return place (in static memory so that it does not count as leak).
|
||||
|
|
@ -405,10 +404,14 @@ pub fn create_ecx<'tcx>(
|
|||
start_instance,
|
||||
Abi::Rust,
|
||||
&[
|
||||
Scalar::from_pointer(main_ptr, &ecx).into(),
|
||||
argc.into(),
|
||||
ImmTy::from_scalar(
|
||||
Scalar::from_pointer(main_ptr, &ecx),
|
||||
// FIXME use a proper fn ptr type
|
||||
ecx.machine.layouts.const_raw_ptr,
|
||||
),
|
||||
argc,
|
||||
argv,
|
||||
Scalar::from_u8(sigpipe).into(),
|
||||
ImmTy::from_uint(sigpipe, ecx.machine.layouts.u8),
|
||||
],
|
||||
Some(&ret_place),
|
||||
StackPopCleanup::Root { cleanup: true },
|
||||
|
|
@ -418,7 +421,7 @@ pub fn create_ecx<'tcx>(
|
|||
ecx.call_function(
|
||||
entry_instance,
|
||||
Abi::Rust,
|
||||
&[argc.into(), argv],
|
||||
&[argc, argv],
|
||||
Some(&ret_place),
|
||||
StackPopCleanup::Root { cleanup: true },
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -12,13 +12,14 @@ use rustc_apfloat::Float;
|
|||
use rustc_hir::{
|
||||
def::{DefKind, Namespace},
|
||||
def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE},
|
||||
Safety,
|
||||
};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::middle::dependency_format::Linkage;
|
||||
use rustc_middle::middle::exported_symbols::ExportedSymbol;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::layout::MaybeResult;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, MaybeResult};
|
||||
use rustc_middle::ty::{
|
||||
self,
|
||||
layout::{LayoutOf, TyAndLayout},
|
||||
|
|
@ -492,48 +493,38 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
&mut self,
|
||||
f: ty::Instance<'tcx>,
|
||||
caller_abi: Abi,
|
||||
args: &[Immediate<Provenance>],
|
||||
args: &[ImmTy<'tcx>],
|
||||
dest: Option<&MPlaceTy<'tcx>>,
|
||||
stack_pop: StackPopCleanup,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let param_env = ty::ParamEnv::reveal_all(); // in Miri this is always the param_env we use... and this.param_env is private.
|
||||
let callee_abi = f.ty(*this.tcx, param_env).fn_sig(*this.tcx).abi();
|
||||
if callee_abi != caller_abi {
|
||||
throw_ub_format!(
|
||||
"calling a function with ABI {} using caller ABI {}",
|
||||
callee_abi.name(),
|
||||
caller_abi.name()
|
||||
)
|
||||
}
|
||||
|
||||
// Push frame.
|
||||
// Get MIR.
|
||||
let mir = this.load_mir(f.def, None)?;
|
||||
let dest = match dest {
|
||||
Some(dest) => dest.clone(),
|
||||
None => MPlaceTy::fake_alloc_zst(this.layout_of(mir.return_ty())?),
|
||||
};
|
||||
this.push_stack_frame(f, mir, &dest, stack_pop)?;
|
||||
|
||||
// Initialize arguments.
|
||||
let mut callee_args = this.frame().body.args_iter();
|
||||
for arg in args {
|
||||
let local = callee_args
|
||||
.next()
|
||||
.ok_or_else(|| err_ub_format!("callee has fewer arguments than expected"))?;
|
||||
// Make the local live, and insert the initial value.
|
||||
this.storage_live(local)?;
|
||||
let callee_arg = this.local_to_place(local)?;
|
||||
this.write_immediate(*arg, &callee_arg)?;
|
||||
}
|
||||
if callee_args.next().is_some() {
|
||||
throw_ub_format!("callee has more arguments than expected");
|
||||
}
|
||||
// Construct a function pointer type representing the caller perspective.
|
||||
let sig = this.tcx.mk_fn_sig(
|
||||
args.iter().map(|a| a.layout.ty),
|
||||
dest.layout.ty,
|
||||
/*c_variadic*/ false,
|
||||
Safety::Safe,
|
||||
caller_abi,
|
||||
);
|
||||
let caller_fn_abi = this.fn_abi_of_fn_ptr(ty::Binder::dummy(sig), ty::List::empty())?;
|
||||
|
||||
// Initialize remaining locals.
|
||||
this.storage_live_for_always_live_locals()?;
|
||||
|
||||
Ok(())
|
||||
this.init_stack_frame(
|
||||
f,
|
||||
mir,
|
||||
caller_fn_abi,
|
||||
&args.iter().map(|a| FnArg::Copy(a.clone().into())).collect::<Vec<_>>(),
|
||||
/*with_caller_location*/ false,
|
||||
&dest,
|
||||
stack_pop,
|
||||
)
|
||||
}
|
||||
|
||||
/// Visits the memory covered by `place`, sensitive to freezing: the 2nd parameter
|
||||
|
|
@ -1114,12 +1105,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Make an attempt to get at the instance of the function this is inlined from.
|
||||
let instance: Option<_> = try {
|
||||
let scope = frame.current_source_info()?.scope;
|
||||
let inlined_parent = frame.body.source_scopes[scope].inlined_parent_scope?;
|
||||
let source = &frame.body.source_scopes[inlined_parent];
|
||||
let inlined_parent = frame.body().source_scopes[scope].inlined_parent_scope?;
|
||||
let source = &frame.body().source_scopes[inlined_parent];
|
||||
source.inlined.expect("inlined_parent_scope points to scope without inline info").0
|
||||
};
|
||||
// Fall back to the instance of the function itself.
|
||||
let instance = instance.unwrap_or(frame.instance);
|
||||
let instance = instance.unwrap_or(frame.instance());
|
||||
// Now check the crate it is in. We could try to be clever here and e.g. check if this is
|
||||
// the same crate as `start_fn`, but that would not work for running std tests in Miri, so
|
||||
// we'd need some more hacks anyway. So we just check the name of the crate. If someone
|
||||
|
|
@ -1359,9 +1350,9 @@ impl<'tcx> MiriMachine<'tcx> {
|
|||
|
||||
/// This is the source of truth for the `is_user_relevant` flag in our `FrameExtra`.
|
||||
pub fn is_user_relevant(&self, frame: &Frame<'tcx, Provenance>) -> bool {
|
||||
let def_id = frame.instance.def_id();
|
||||
let def_id = frame.instance().def_id();
|
||||
(def_id.is_local() || self.local_crates.contains(&def_id.krate))
|
||||
&& !frame.instance.def.requires_caller_location(self.tcx)
|
||||
&& !frame.instance().def.requires_caller_location(self.tcx)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1352,7 +1352,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
|||
) -> InterpResult<'tcx, Frame<'tcx, Provenance, FrameExtra<'tcx>>> {
|
||||
// Start recording our event before doing anything else
|
||||
let timing = if let Some(profiler) = ecx.machine.profiler.as_ref() {
|
||||
let fn_name = frame.instance.to_string();
|
||||
let fn_name = frame.instance().to_string();
|
||||
let entry = ecx.machine.string_cache.entry(fn_name.clone());
|
||||
let name = entry.or_insert_with(|| profiler.alloc_string(&*fn_name));
|
||||
|
||||
|
|
@ -1443,7 +1443,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
|||
// tracing-tree can autoamtically annotate scope changes, but it gets very confused by our
|
||||
// concurrency and what it prints is just plain wrong. So we print our own information
|
||||
// instead. (Cc https://github.com/rust-lang/miri/issues/2266)
|
||||
info!("Leaving {}", ecx.frame().instance);
|
||||
info!("Leaving {}", ecx.frame().instance());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -1473,7 +1473,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
|||
// Needs to be done after dropping frame to show up on the right nesting level.
|
||||
// (Cc https://github.com/rust-lang/miri/issues/2266)
|
||||
if !ecx.active_thread_stack().is_empty() {
|
||||
info!("Continuing in {}", ecx.frame().instance);
|
||||
info!("Continuing in {}", ecx.frame().instance());
|
||||
}
|
||||
res
|
||||
}
|
||||
|
|
@ -1486,7 +1486,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
|||
let Some(Provenance::Concrete { alloc_id, .. }) = mplace.ptr().provenance else {
|
||||
panic!("after_local_allocated should only be called on fresh allocations");
|
||||
};
|
||||
let local_decl = &ecx.frame().body.local_decls[local];
|
||||
let local_decl = &ecx.frame().body().local_decls[local];
|
||||
let span = local_decl.source_info.span;
|
||||
ecx.machine.allocation_spans.borrow_mut().insert(alloc_id, (span, None));
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let mut data = Vec::new();
|
||||
for frame in this.active_thread_stack().iter().rev() {
|
||||
// Match behavior of debuginfo (`FunctionCx::adjusted_span_and_dbg_scope`).
|
||||
let span = hygiene::walk_chain_collapsed(frame.current_span(), frame.body.span);
|
||||
data.push((frame.instance, span.lo()));
|
||||
let span = hygiene::walk_chain_collapsed(frame.current_span(), frame.body().span);
|
||||
data.push((frame.instance(), span.lo()));
|
||||
}
|
||||
|
||||
let ptrs: Vec<_> = data
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ pub struct CatchUnwindData<'tcx> {
|
|||
/// The `catch_fn` callback to call in case of a panic.
|
||||
catch_fn: Pointer,
|
||||
/// The `data` argument for that callback.
|
||||
data: Scalar,
|
||||
data: ImmTy<'tcx>,
|
||||
/// The return place from the original call to `try`.
|
||||
dest: MPlaceTy<'tcx>,
|
||||
/// The return block from the original call to `try`.
|
||||
|
|
@ -48,9 +48,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
fn handle_miri_start_unwind(&mut self, payload: &OpTy<'tcx>) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
trace!("miri_start_unwind: {:?}", this.frame().instance);
|
||||
trace!("miri_start_unwind: {:?}", this.frame().instance());
|
||||
|
||||
let payload = this.read_scalar(payload)?;
|
||||
let payload = this.read_immediate(payload)?;
|
||||
let thread = this.active_thread_mut();
|
||||
thread.panic_payloads.push(payload);
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Get all the arguments.
|
||||
let [try_fn, data, catch_fn] = check_arg_count(args)?;
|
||||
let try_fn = this.read_pointer(try_fn)?;
|
||||
let data = this.read_scalar(data)?;
|
||||
let data = this.read_immediate(data)?;
|
||||
let catch_fn = this.read_pointer(catch_fn)?;
|
||||
|
||||
// Now we make a function call, and pass `data` as first and only argument.
|
||||
|
|
@ -89,7 +89,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.call_function(
|
||||
f_instance,
|
||||
Abi::Rust,
|
||||
&[data.into()],
|
||||
&[data.clone()],
|
||||
None,
|
||||
// Directly return to caller.
|
||||
StackPopCleanup::Goto { ret, unwind: mir::UnwindAction::Continue },
|
||||
|
|
@ -124,7 +124,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// and we are unwinding, so we should catch that.
|
||||
trace!(
|
||||
"unwinding: found catch_panic frame during unwinding: {:?}",
|
||||
this.frame().instance
|
||||
this.frame().instance()
|
||||
);
|
||||
|
||||
// We set the return value of `try` to 1, since there was a panic.
|
||||
|
|
@ -140,7 +140,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.call_function(
|
||||
f_instance,
|
||||
Abi::Rust,
|
||||
&[catch_unwind.data.into(), payload.into()],
|
||||
&[catch_unwind.data, payload],
|
||||
None,
|
||||
// Directly return to caller of `try`.
|
||||
StackPopCleanup::Goto {
|
||||
|
|
@ -169,7 +169,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.call_function(
|
||||
panic,
|
||||
Abi::Rust,
|
||||
&[msg.to_ref(this)],
|
||||
&[this.mplace_to_ref(&msg)?],
|
||||
None,
|
||||
StackPopCleanup::Goto { ret: None, unwind },
|
||||
)
|
||||
|
|
@ -188,7 +188,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.call_function(
|
||||
panic,
|
||||
Abi::Rust,
|
||||
&[msg.to_ref(this)],
|
||||
&[this.mplace_to_ref(&msg)?],
|
||||
None,
|
||||
StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
|
||||
)
|
||||
|
|
@ -207,9 +207,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Forward to `panic_bounds_check` lang item.
|
||||
|
||||
// First arg: index.
|
||||
let index = this.read_scalar(&this.eval_operand(index, None)?)?;
|
||||
let index = this.read_immediate(&this.eval_operand(index, None)?)?;
|
||||
// Second arg: len.
|
||||
let len = this.read_scalar(&this.eval_operand(len, None)?)?;
|
||||
let len = this.read_immediate(&this.eval_operand(len, None)?)?;
|
||||
|
||||
// Call the lang item.
|
||||
let panic_bounds_check = this.tcx.lang_items().panic_bounds_check_fn().unwrap();
|
||||
|
|
@ -217,7 +217,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.call_function(
|
||||
panic_bounds_check,
|
||||
Abi::Rust,
|
||||
&[index.into(), len.into()],
|
||||
&[index, len],
|
||||
None,
|
||||
StackPopCleanup::Goto { ret: None, unwind },
|
||||
)?;
|
||||
|
|
@ -226,9 +226,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Forward to `panic_misaligned_pointer_dereference` lang item.
|
||||
|
||||
// First arg: required.
|
||||
let required = this.read_scalar(&this.eval_operand(required, None)?)?;
|
||||
let required = this.read_immediate(&this.eval_operand(required, None)?)?;
|
||||
// Second arg: found.
|
||||
let found = this.read_scalar(&this.eval_operand(found, None)?)?;
|
||||
let found = this.read_immediate(&this.eval_operand(found, None)?)?;
|
||||
|
||||
// Call the lang item.
|
||||
let panic_misaligned_pointer_dereference =
|
||||
|
|
@ -238,7 +238,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.call_function(
|
||||
panic_misaligned_pointer_dereference,
|
||||
Abi::Rust,
|
||||
&[required.into(), found.into()],
|
||||
&[required, found],
|
||||
None,
|
||||
StackPopCleanup::Goto { ret: None, unwind },
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -315,6 +315,8 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// FIXME: Technically, the reason should be `DLL_PROCESS_DETACH` when the main thread exits
|
||||
// but std treats both the same.
|
||||
let reason = this.eval_windows("c", "DLL_THREAD_DETACH");
|
||||
let null_ptr =
|
||||
ImmTy::from_scalar(Scalar::null_ptr(this), this.machine.layouts.const_raw_ptr);
|
||||
|
||||
// The signature of this function is `unsafe extern "system" fn(h: c::LPVOID, dwReason: c::DWORD, pv: c::LPVOID)`.
|
||||
// FIXME: `h` should be a handle to the current module and what `pv` should be is unknown
|
||||
|
|
@ -322,7 +324,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.call_function(
|
||||
thread_callback,
|
||||
Abi::System { unwind: false },
|
||||
&[Scalar::null_ptr(this).into(), reason.into(), Scalar::null_ptr(this).into()],
|
||||
&[null_ptr.clone(), ImmTy::from_scalar(reason, this.machine.layouts.u32), null_ptr],
|
||||
None,
|
||||
StackPopCleanup::Root { cleanup: true },
|
||||
)?;
|
||||
|
|
@ -343,7 +345,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.call_function(
|
||||
instance,
|
||||
Abi::C { unwind: false },
|
||||
&[data.into()],
|
||||
&[ImmTy::from_scalar(data, this.machine.layouts.mut_raw_ptr)],
|
||||
None,
|
||||
StackPopCleanup::Root { cleanup: true },
|
||||
)?;
|
||||
|
|
@ -380,7 +382,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.call_function(
|
||||
instance,
|
||||
Abi::C { unwind: false },
|
||||
&[ptr.into()],
|
||||
&[ImmTy::from_scalar(ptr, this.machine.layouts.mut_raw_ptr)],
|
||||
None,
|
||||
StackPopCleanup::Root { cleanup: true },
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use crate::*;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
|
|
@ -24,7 +23,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
start_routine,
|
||||
Abi::C { unwind: false },
|
||||
func_arg,
|
||||
this.layout_of(this.tcx.types.usize)?,
|
||||
this.machine.layouts.mut_raw_ptr,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
//@ignore-target-windows: No pthreads on Windows
|
||||
//~^ERROR: calling a function with more arguments than it expected
|
||||
|
||||
//! The thread function must have exactly one argument.
|
||||
|
||||
use std::{mem, ptr};
|
||||
|
||||
extern "C" fn thread_start() -> *mut libc::c_void {
|
||||
panic!() //~ ERROR: callee has fewer arguments than expected
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
error: Undefined Behavior: callee has fewer arguments than expected
|
||||
--> $DIR/libc_pthread_create_too_few_args.rs:LL:CC
|
||||
|
|
||||
LL | panic!()
|
||||
| ^^^^^^^^ callee has fewer arguments than expected
|
||||
error: Undefined Behavior: calling a function with more arguments than it expected
|
||||
|
|
||||
= note: calling a function with more arguments than it expected
|
||||
= note: (no span available)
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE on thread `unnamed-ID`:
|
||||
= note: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC
|
||||
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
//@ignore-target-windows: No pthreads on Windows
|
||||
//~^ERROR: calling a function with fewer arguments than it requires
|
||||
|
||||
//! The thread function must have exactly one argument.
|
||||
|
||||
use std::{mem, ptr};
|
||||
|
||||
extern "C" fn thread_start(_null: *mut libc::c_void, _x: i32) -> *mut libc::c_void {
|
||||
panic!() //~ ERROR: callee has more arguments than expected
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
error: Undefined Behavior: callee has more arguments than expected
|
||||
--> $DIR/libc_pthread_create_too_many_args.rs:LL:CC
|
||||
|
|
||||
LL | panic!()
|
||||
| ^^^^^^^^ callee has more arguments than expected
|
||||
error: Undefined Behavior: calling a function with fewer arguments than it requires
|
||||
|
|
||||
= note: calling a function with fewer arguments than it requires
|
||||
= note: (no span available)
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE on thread `unnamed-ID`:
|
||||
= note: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC
|
||||
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ fn main() {
|
|||
// Make sure we check the ABI when Miri itself invokes a function
|
||||
// as part of a shim implementation.
|
||||
std::intrinsics::catch_unwind(
|
||||
//~^ ERROR: calling a function with ABI C using caller ABI Rust
|
||||
//~^ ERROR: calling a function with calling convention C using calling convention Rust
|
||||
std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
|
||||
std::ptr::null_mut(),
|
||||
|_, _| unreachable!(),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: Undefined Behavior: calling a function with ABI C using caller ABI Rust
|
||||
error: Undefined Behavior: calling a function with calling convention C using calling convention Rust
|
||||
--> $DIR/check_callback_abi.rs:LL:CC
|
||||
|
|
||||
LL | / std::intrinsics::catch_unwind(
|
||||
|
|
@ -7,7 +7,7 @@ LL | | std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
|
|||
LL | | std::ptr::null_mut(),
|
||||
LL | | |_, _| unreachable!(),
|
||||
LL | | );
|
||||
| |_________^ calling a function with ABI C using caller ABI Rust
|
||||
| |_________^ calling a function with calling convention C using calling convention Rust
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#![feature(start)]
|
||||
#![no_std]
|
||||
//@compile-flags: -Zmiri-track-alloc-id=20 -Zmiri-track-alloc-accesses -Cpanic=abort
|
||||
//@normalize-stderr-test: "id 20" -> "id $$ALLOC"
|
||||
//@compile-flags: -Zmiri-track-alloc-id=21 -Zmiri-track-alloc-accesses -Cpanic=abort
|
||||
//@normalize-stderr-test: "id 21" -> "id $$ALLOC"
|
||||
//@only-target-linux: alloc IDs differ between OSes (due to extern static allocations)
|
||||
|
||||
extern "Rust" {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue