Support use of asm goto with outputs and options(noreturn)
When labels are present, the `noreturn` option really means that asm block won't fallthrough -- if labels are present, then outputs can still be meaningfully used.
This commit is contained in:
parent
b8df869ebb
commit
73f8309300
5 changed files with 45 additions and 5 deletions
|
|
@ -300,7 +300,10 @@ pub fn parse_asm_args<'a>(
|
|||
if args.options.contains(ast::InlineAsmOptions::PURE) && !have_real_output {
|
||||
dcx.emit_err(errors::AsmPureNoOutput { spans: args.options_spans.clone() });
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::NORETURN) && !outputs_sp.is_empty() {
|
||||
if args.options.contains(ast::InlineAsmOptions::NORETURN)
|
||||
&& !outputs_sp.is_empty()
|
||||
&& labels_sp.is_empty()
|
||||
{
|
||||
let err = dcx.create_err(errors::AsmNoReturn { outputs_sp });
|
||||
// Bail out now since this is likely to confuse MIR
|
||||
return Err(err);
|
||||
|
|
|
|||
|
|
@ -343,7 +343,14 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs });
|
||||
|
||||
// Write results to outputs. We need to do this for all possible control flow.
|
||||
for block in Some(dest).into_iter().chain(labels.iter().copied().map(Some)) {
|
||||
//
|
||||
// Note that `dest` maybe populated with unreachable_block when asm goto with outputs
|
||||
// is used (because we need to codegen callbr which always needs a destination), so
|
||||
// here we use the NORETURN option to determine if `dest` should be used.
|
||||
for block in (if options.contains(InlineAsmOptions::NORETURN) { None } else { Some(dest) })
|
||||
.into_iter()
|
||||
.chain(labels.iter().copied().map(Some))
|
||||
{
|
||||
if let Some(block) = block {
|
||||
self.switch_to_block(block);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue