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

Commit 887999d

Browse files
committed
Auto merge of rust-lang#88439 - cynecx:unwind_asm, r=Amanieu
Unwinding support for inline assembly r? `@Amanieu`
2 parents f581572 + 3dbb621 commit 887999d

File tree

55 files changed

+623
-232
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+623
-232
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1981,7 +1981,7 @@ pub enum InlineAsmRegOrRegClass {
19811981

19821982
bitflags::bitflags! {
19831983
#[derive(Encodable, Decodable, HashStable_Generic)]
1984-
pub struct InlineAsmOptions: u8 {
1984+
pub struct InlineAsmOptions: u16 {
19851985
const PURE = 1 << 0;
19861986
const NOMEM = 1 << 1;
19871987
const READONLY = 1 << 2;
@@ -1990,6 +1990,7 @@ bitflags::bitflags! {
19901990
const NOSTACK = 1 << 5;
19911991
const ATT_SYNTAX = 1 << 6;
19921992
const RAW = 1 << 7;
1993+
const MAY_UNWIND = 1 << 8;
19931994
}
19941995
}
19951996

compiler/rustc_ast_lowering/src/asm.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
4949
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
5050
.emit();
5151
}
52+
if asm.options.contains(InlineAsmOptions::MAY_UNWIND)
53+
&& !self.sess.features_untracked().asm_unwind
54+
{
55+
feature_err(
56+
&self.sess.parse_sess,
57+
sym::asm_unwind,
58+
sp,
59+
"the `may_unwind` option is unstable",
60+
)
61+
.emit();
62+
}
5263

5364
let mut clobber_abis = FxHashMap::default();
5465
if let Some(asm_arch) = asm_arch {

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,6 +2338,9 @@ impl<'a> State<'a> {
23382338
if opts.contains(InlineAsmOptions::RAW) {
23392339
options.push("raw");
23402340
}
2341+
if opts.contains(InlineAsmOptions::MAY_UNWIND) {
2342+
options.push("may_unwind");
2343+
}
23412344
s.commasep(Inconsistent, &options, |s, &opt| {
23422345
s.word(opt);
23432346
});

compiler/rustc_borrowck/src/dataflow.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_middle::ty::RegionVid;
55
use rustc_middle::ty::TyCtxt;
66
use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
77
use rustc_mir_dataflow::ResultsVisitable;
8-
use rustc_mir_dataflow::{self, fmt::DebugWithContext, GenKill};
8+
use rustc_mir_dataflow::{self, fmt::DebugWithContext, CallReturnPlaces, GenKill};
99
use rustc_mir_dataflow::{Analysis, Direction, Results};
1010
use std::fmt;
1111
use std::iter;
@@ -434,9 +434,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
434434
&self,
435435
_trans: &mut impl GenKill<Self::Idx>,
436436
_block: mir::BasicBlock,
437-
_func: &mir::Operand<'tcx>,
438-
_args: &[mir::Operand<'tcx>],
439-
_dest_place: mir::Place<'tcx>,
437+
_return_places: CallReturnPlaces<'_, 'tcx>,
440438
) {
441439
}
442440
}

compiler/rustc_borrowck/src/def_use.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
1717
PlaceContext::MutatingUse(MutatingUseContext::Store) |
1818

1919
// This is potentially both a def and a use...
20-
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) |
20+
PlaceContext::MutatingUse(MutatingUseContext::LlvmAsmOutput) |
2121

2222
// We let Call define the result in both the success and
2323
// unwind cases. This is not really correct, however it
@@ -26,6 +26,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
2626
// the def in call only to the input from the success
2727
// path and not the unwind path. -nmatsakis
2828
PlaceContext::MutatingUse(MutatingUseContext::Call) |
29+
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) |
2930
PlaceContext::MutatingUse(MutatingUseContext::Yield) |
3031

3132
// Storage live and storage dead aren't proper defines, but we can ignore

compiler/rustc_borrowck/src/invalidation.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
199199
options: _,
200200
line_spans: _,
201201
destination: _,
202+
cleanup: _,
202203
} => {
203204
for op in operands {
204205
match *op {

compiler/rustc_borrowck/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
791791
options: _,
792792
line_spans: _,
793793
destination: _,
794+
cleanup: _,
794795
} => {
795796
for op in operands {
796797
match *op {

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1828,10 +1828,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
18281828
self.assert_iscleanup(body, block_data, unwind, true);
18291829
}
18301830
}
1831-
TerminatorKind::InlineAsm { destination, .. } => {
1831+
TerminatorKind::InlineAsm { destination, cleanup, .. } => {
18321832
if let Some(target) = destination {
18331833
self.assert_iscleanup(body, block_data, target, is_cleanup);
18341834
}
1835+
if let Some(cleanup) = cleanup {
1836+
if is_cleanup {
1837+
span_mirbug!(self, block_data, "cleanup on cleanup block")
1838+
}
1839+
self.assert_iscleanup(body, block_data, cleanup, true);
1840+
}
18351841
}
18361842
}
18371843
}

compiler/rustc_builtin_macros/src/asm.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,8 @@ fn parse_options<'a>(
420420
try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX);
421421
} else if p.eat_keyword(kw::Raw) {
422422
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::RAW);
423+
} else if p.eat_keyword(sym::may_unwind) {
424+
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::MAY_UNWIND);
423425
} else {
424426
return p.unexpected();
425427
}

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Codegen of a single function
22
33
use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
4+
use rustc_ast::InlineAsmOptions;
45
use rustc_index::vec::IndexVec;
56
use rustc_middle::ty::adjustment::PointerCast;
67
use rustc_middle::ty::layout::FnAbiOf;
@@ -239,7 +240,8 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
239240
fx.add_comment(inst, terminator_head);
240241
}
241242

242-
fx.set_debug_loc(bb_data.terminator().source_info);
243+
let source_info = bb_data.terminator().source_info;
244+
fx.set_debug_loc(source_info);
243245

244246
match &bb_data.terminator().kind {
245247
TerminatorKind::Goto { target } => {
@@ -295,19 +297,19 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
295297
let len = codegen_operand(fx, len).load_scalar(fx);
296298
let index = codegen_operand(fx, index).load_scalar(fx);
297299
let location = fx
298-
.get_caller_location(bb_data.terminator().source_info.span)
300+
.get_caller_location(source_info.span)
299301
.load_scalar(fx);
300302

301303
codegen_panic_inner(
302304
fx,
303305
rustc_hir::LangItem::PanicBoundsCheck,
304306
&[index, len, location],
305-
bb_data.terminator().source_info.span,
307+
source_info.span,
306308
);
307309
}
308310
_ => {
309311
let msg_str = msg.description();
310-
codegen_panic(fx, msg_str, bb_data.terminator().source_info.span);
312+
codegen_panic(fx, msg_str, source_info.span);
311313
}
312314
}
313315
}
@@ -378,10 +380,18 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
378380
options,
379381
destination,
380382
line_spans: _,
383+
cleanup: _,
381384
} => {
385+
if options.contains(InlineAsmOptions::MAY_UNWIND) {
386+
fx.tcx.sess.span_fatal(
387+
source_info.span,
388+
"cranelift doesn't support unwinding from inline assembly.",
389+
);
390+
}
391+
382392
crate::inline_asm::codegen_inline_asm(
383393
fx,
384-
bb_data.terminator().source_info.span,
394+
source_info.span,
385395
template,
386396
operands,
387397
*options,
@@ -415,7 +425,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
415425
}
416426
TerminatorKind::Drop { place, target, unwind: _ } => {
417427
let drop_place = codegen_place(fx, *place);
418-
crate::abi::codegen_drop(fx, bb_data.terminator().source_info.span, drop_place);
428+
crate::abi::codegen_drop(fx, source_info.span, drop_place);
419429

420430
let target_block = fx.get_block(*target);
421431
fx.bcx.ins().jump(target_block, &[]);

0 commit comments

Comments
 (0)