Skip to content

Commit 5fbb4d7

Browse files
adpaco-awstedinski
authored andcommitted
Handle non returning intrinsics (rust-lang#736)
* Handle non returning intrinsics * Newline in comment * Address comments
1 parent f0e4d05 commit 5fbb4d7

File tree

5 files changed

+63
-23
lines changed

5 files changed

+63
-23
lines changed

src/rmc-compiler/rustc_codegen_rmc/src/codegen/intrinsic.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ impl<'tcx> GotocCtx<'tcx> {
2929
self.codegen_expr_to_place(p, e)
3030
}
3131

32+
/// Handles codegen for non returning intrinsics
33+
/// Non returning intrinsics are not associated with a destination
34+
pub fn codegen_never_return_intrinsic(
35+
&mut self,
36+
instance: Instance<'tcx>,
37+
span: Option<Span>,
38+
) -> Stmt {
39+
let intrinsic = self.symbol_name(instance);
40+
let intrinsic = intrinsic.as_str();
41+
42+
debug!("codegen_never_return_intrinsic:\n\tinstance {:?}\n\tspan {:?}", instance, span);
43+
44+
match intrinsic {
45+
"abort" => self.codegen_fatal_error("reached intrinsic::abort", span),
46+
"transmute" => self.codegen_fatal_error("transmuting to uninhabited type", span),
47+
_ => unimplemented!(),
48+
}
49+
}
50+
3251
/// c.f. rustc_codegen_llvm::intrinsic impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx>
3352
/// fn codegen_intrinsic_call
3453
/// c.f. https://doc.rust-lang.org/std/intrinsics/index.html
@@ -280,7 +299,6 @@ impl<'tcx> GotocCtx<'tcx> {
280299
}
281300

282301
match intrinsic {
283-
"abort" => Stmt::assert_false("abort intrinsic", loc),
284302
"add_with_overflow" => codegen_op_with_overflow!(add_overflow),
285303
"arith_offset" => codegen_wrapping_op!(plus),
286304
"assert_inhabited" => {

src/rmc-compiler/rustc_codegen_rmc/src/overrides/hooks.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -255,19 +255,19 @@ impl<'tcx> GotocHook<'tcx> for Intrinsic {
255255
target: Option<BasicBlock>,
256256
span: Option<Span>,
257257
) -> Stmt {
258-
let loc = tcx.codegen_span_option(span);
259-
if tcx.symbol_name(instance) == "abort" {
260-
Stmt::assert_false("abort intrinsic reached", loc)
261-
} else {
262-
let p = assign_to.unwrap();
263-
let target = target.unwrap();
264-
Stmt::block(
265-
vec![
266-
tcx.codegen_intrinsic(instance, fargs, &p, span),
267-
Stmt::goto(tcx.current_fn().find_label(&target), loc.clone()),
268-
],
269-
loc,
270-
)
258+
match assign_to {
259+
None => tcx.codegen_never_return_intrinsic(instance, span),
260+
Some(assign_to) => {
261+
let target = target.unwrap();
262+
let loc = tcx.codegen_span_option(span);
263+
Stmt::block(
264+
vec![
265+
tcx.codegen_intrinsic(instance, fargs, &assign_to, span),
266+
Stmt::goto(tcx.current_fn().find_label(&target), loc.clone()),
267+
],
268+
loc,
269+
)
270+
}
271271
}
272272
}
273273
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
// rmc-verify-fail
4+
5+
#![feature(core_intrinsics)]
6+
7+
// Aborts the execution of the process
8+
//
9+
// The current implementation in Rust is to invoke an invalid instruction on
10+
// most platforms. On Unix, the process terminates with a signal like `SIGABRT`,
11+
// `SIGILL`, `SIGTRAP`, `SIGSEGV` or `SIGBUS`.
12+
//
13+
// The documentation mentions that `std::process::abort` is preferred if
14+
// possible: https://doc.rust-lang.org/core/intrinsics/fn.abort.html
15+
// In RMC, `std::process::abort` is identified as a panicking function
16+
fn main() {
17+
std::intrinsics::abort();
18+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
// rmc-verify-fail
4+
5+
#![feature(never_type)]
6+
7+
// Transmutes an inhabited ZST into a uninhabited ZST
8+
//
9+
// Handled as a special case of transmute (non returning intrinsic) that
10+
// compiles but crashes at runtime, similar to calling `std::intrinsic::abort`
11+
fn main() {
12+
unsafe { std::mem::transmute::<(), !>(()) };
13+
}

src/test/rmc/Intrinsics/abort.rs

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)