Skip to content

Commit 28fbf81

Browse files
committed
Auto merge of #1823 - hyd-dev:extern-crate-std, r=RalfJung
Detect `std` by checking if the crate defines `#[lang = "start"]` rather than string comparison I also considered to compare the crate name with `sym::std`, but it's easy to name any crate `std` by using `--crate-name std`, so I don't think that is robust enough. Note that this only checks the crate, it does not check whether the call is in `sys::unix` or `sys::windows`, unlike the previous implementation, but I think it's already robust enough. Fixes #1821.
2 parents 28717a0 + 0ece55d commit 28fbf81

File tree

8 files changed

+44
-25
lines changed

8 files changed

+44
-25
lines changed

src/helpers.rs

+8
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
628628
}
629629
Ok(())
630630
}
631+
632+
fn frame_in_std(&self) -> bool {
633+
let this = self.eval_context_ref();
634+
this.tcx.lang_items().start_fn().map_or(false, |start_fn| {
635+
this.tcx.def_path(this.frame().instance.def_id()).krate
636+
== this.tcx.def_path(start_fn).krate
637+
})
638+
}
631639
}
632640

633641
/// Check that the number of args is what we expect.

src/shims/posix/foreign_items.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
475475
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
476476
// These shims are enabled only when the caller is in the standard library.
477477
"pthread_attr_getguardsize"
478-
if this.frame().instance.to_string().starts_with("std::sys::unix::") => {
478+
if this.frame_in_std() => {
479479
this.check_abi(abi, Abi::C { unwind: false })?;
480480
let &[ref _attr, ref guard_size] = check_arg_count(args)?;
481481
let guard_size = this.deref_operand(guard_size)?;
@@ -488,28 +488,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
488488

489489
| "pthread_attr_init"
490490
| "pthread_attr_destroy"
491-
if this.frame().instance.to_string().starts_with("std::sys::unix::") => {
491+
if this.frame_in_std() => {
492492
this.check_abi(abi, Abi::C { unwind: false })?;
493493
let &[_] = check_arg_count(args)?;
494494
this.write_null(dest)?;
495495
}
496496
| "pthread_attr_setstacksize"
497-
if this.frame().instance.to_string().starts_with("std::sys::unix::") => {
497+
if this.frame_in_std() => {
498498
this.check_abi(abi, Abi::C { unwind: false })?;
499499
let &[_, _] = check_arg_count(args)?;
500500
this.write_null(dest)?;
501501
}
502502

503503
| "signal"
504504
| "sigaltstack"
505-
if this.frame().instance.to_string().starts_with("std::sys::unix::") => {
505+
if this.frame_in_std() => {
506506
this.check_abi(abi, Abi::C { unwind: false })?;
507507
let &[_, _] = check_arg_count(args)?;
508508
this.write_null(dest)?;
509509
}
510510
| "sigaction"
511511
| "mprotect"
512-
if this.frame().instance.to_string().starts_with("std::sys::unix::") => {
512+
if this.frame_in_std() => {
513513
this.check_abi(abi, Abi::C { unwind: false })?;
514514
let &[_, _, _] = check_arg_count(args)?;
515515
this.write_null(dest)?;

src/shims/posix/linux/foreign_items.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
207207

208208
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
209209
// These shims are enabled only when the caller is in the standard library.
210-
"pthread_getattr_np"
211-
if this.frame().instance.to_string().starts_with("std::sys::unix::") =>
212-
{
210+
"pthread_getattr_np" if this.frame_in_std() => {
213211
this.check_abi(abi, Abi::C { unwind: false })?;
214212
let &[ref _thread, ref _attr] = check_arg_count(args)?;
215213
this.write_null(dest)?;

src/shims/posix/macos/foreign_items.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
149149

150150
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
151151
// These shims are enabled only when the caller is in the standard library.
152-
"mmap" if this.frame().instance.to_string().starts_with("std::sys::unix::") => {
152+
"mmap" if this.frame_in_std() => {
153153
this.check_abi(abi, Abi::C { unwind: false })?;
154154
// This is a horrible hack, but since the guard page mechanism calls mmap and expects a particular return value, we just give it that value.
155155
let &[ref addr, _, _, _, _, _] = check_arg_count(args)?;

src/shims/windows/foreign_items.rs

+6-16
Original file line numberDiff line numberDiff line change
@@ -348,35 +348,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
348348

349349
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
350350
// These shims are enabled only when the caller is in the standard library.
351-
"GetProcessHeap"
352-
if this.frame().instance.to_string().starts_with("std::sys::windows::") =>
353-
{
351+
"GetProcessHeap" if this.frame_in_std() => {
354352
this.check_abi(abi, Abi::System { unwind: false })?;
355353
let &[] = check_arg_count(args)?;
356354
// Just fake a HANDLE
357355
this.write_scalar(Scalar::from_machine_isize(1, this), dest)?;
358356
}
359-
"SetConsoleTextAttribute"
360-
if this.frame().instance.to_string().starts_with("std::sys::windows::") =>
361-
{
357+
"SetConsoleTextAttribute" if this.frame_in_std() => {
362358
this.check_abi(abi, Abi::System { unwind: false })?;
363359
#[allow(non_snake_case)]
364360
let &[ref _hConsoleOutput, ref _wAttribute] = check_arg_count(args)?;
365361
// Pretend these does not exist / nothing happened, by returning zero.
366362
this.write_null(dest)?;
367363
}
368-
"AddVectoredExceptionHandler"
369-
if this.frame().instance.to_string().starts_with("std::sys::windows::") =>
370-
{
364+
"AddVectoredExceptionHandler" if this.frame_in_std() => {
371365
this.check_abi(abi, Abi::System { unwind: false })?;
372366
#[allow(non_snake_case)]
373367
let &[ref _First, ref _Handler] = check_arg_count(args)?;
374368
// Any non zero value works for the stdlib. This is just used for stack overflows anyway.
375369
this.write_scalar(Scalar::from_machine_usize(1, this), dest)?;
376370
}
377-
"SetThreadStackGuarantee"
378-
if this.frame().instance.to_string().starts_with("std::sys::windows::") =>
379-
{
371+
"SetThreadStackGuarantee" if this.frame_in_std() => {
380372
this.check_abi(abi, Abi::System { unwind: false })?;
381373
#[allow(non_snake_case)]
382374
let &[_StackSizeInBytes] = check_arg_count(args)?;
@@ -387,7 +379,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
387379
| "EnterCriticalSection"
388380
| "LeaveCriticalSection"
389381
| "DeleteCriticalSection"
390-
if this.frame().instance.to_string().starts_with("std::sys::windows::") =>
382+
if this.frame_in_std() =>
391383
{
392384
this.check_abi(abi, Abi::System { unwind: false })?;
393385
#[allow(non_snake_case)]
@@ -401,9 +393,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
401393
// (Windows locks are reentrant, and we have only 1 thread,
402394
// so not doing any futher checks here is at least not incorrect.)
403395
}
404-
"TryEnterCriticalSection"
405-
if this.frame().instance.to_string().starts_with("std::sys::windows::") =>
406-
{
396+
"TryEnterCriticalSection" if this.frame_in_std() => {
407397
this.check_abi(abi, Abi::System { unwind: false })?;
408398
#[allow(non_snake_case)]
409399
let &[ref _lpCriticalSection] = check_arg_count(args)?;
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! `signal()` is special on Linux and macOS that it's only supported within libstd.
2+
//! The implementation is not complete enough to permit user code to call it.
3+
// ignore-windows: No libc on Windows
4+
#![feature(rustc_private)]
5+
6+
extern crate libc;
7+
8+
fn main() {
9+
unsafe {
10+
libc::signal(libc::SIGPIPE, libc::SIG_IGN);
11+
//~^ ERROR unsupported operation: can't call foreign function: signal
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![no_std]
2+
3+
fn main() {
4+
extern crate std;
5+
}

tests/run-pass/rename_std.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![no_std]
2+
3+
extern crate std as foo;
4+
5+
fn main() {}

0 commit comments

Comments
 (0)