Skip to content

Commit c38f13b

Browse files
committed
Implement asm_const_ptr for inline asm
1 parent 0947c84 commit c38f13b

File tree

12 files changed

+100
-68
lines changed

12 files changed

+100
-68
lines changed

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,14 +1230,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12301230
InlineAsmOperandRef::InOut { reg, late, in_value, out_place }
12311231
}
12321232
mir::InlineAsmOperand::Const { ref value } => {
1233-
let const_value = self.eval_mir_constant(value);
1234-
let string = common::asm_const_to_str(
1235-
bx.tcx(),
1236-
span,
1237-
const_value,
1238-
bx.layout_of(value.ty()),
1239-
);
1240-
InlineAsmOperandRef::Interpolate { string }
1233+
if value.ty().is_any_ptr() {
1234+
let value = self.eval_mir_constant_to_operand(bx, value);
1235+
InlineAsmOperandRef::Const { value }
1236+
} else {
1237+
let const_value = self.eval_mir_constant(value);
1238+
let string = common::asm_const_to_str(
1239+
bx.tcx(),
1240+
span,
1241+
const_value,
1242+
bx.layout_of(value.ty()),
1243+
);
1244+
InlineAsmOperandRef::Interpolate { string }
1245+
}
12411246
}
12421247
mir::InlineAsmOperand::SymFn { ref value } => {
12431248
let const_ = self.monomorphize(value.const_);

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,8 @@ declare_features! (
372372
(unstable, arbitrary_self_types, "1.23.0", Some(44874)),
373373
/// Allows inherent and trait methods with arbitrary self types that are raw pointers.
374374
(unstable, arbitrary_self_types_pointers, "1.83.0", Some(44874)),
375+
/// Allows using `const` operands with pointer in inline assembly.
376+
(unstable, asm_const_ptr, "CURRENT_RUSTC_VERSION", Some(128464)),
375377
/// Enables experimental inline assembly support for additional architectures.
376378
(unstable, asm_experimental_arch, "1.58.0", Some(93335)),
377379
/// Enables experimental register support in inline assembly.

compiler/rustc_hir_typeck/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but
1111
.note = we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new
1212
1313
hir_typeck_as_deref_suggestion = consider using `as_deref` here
14+
15+
hir_typeck_asm_const_ptr_unstable =
16+
using pointers in asm `const` operand is experimental
17+
1418
hir_typeck_base_expression_double_dot = base expression required after `..`
1519
hir_typeck_base_expression_double_dot_add_expr = add a base expression here
1620
hir_typeck_base_expression_double_dot_enable_default_field_values =

compiler/rustc_hir_typeck/src/errors.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ use rustc_span::{Ident, Span, Symbol};
1414

1515
use crate::fluent_generated as fluent;
1616

17+
#[derive(Diagnostic)]
18+
#[diag(hir_typeck_asm_const_ptr_unstable)]
19+
pub(crate) struct AsmConstPtrUnstable {
20+
#[primary_span]
21+
pub span: Span,
22+
}
23+
1724
#[derive(Diagnostic)]
1825
#[diag(hir_typeck_base_expression_double_dot, code = E0797)]
1926
pub(crate) struct BaseExpressionDoubleDot {

compiler/rustc_hir_typeck/src/inline_asm.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_target::asm::{
1414
use rustc_trait_selection::infer::InferCtxtExt;
1515

1616
use crate::FnCtxt;
17-
use crate::errors::RegisterTypeUnstable;
17+
use crate::errors::{AsmConstPtrUnstable, RegisterTypeUnstable};
1818

1919
pub(crate) struct InlineAsmCtxt<'a, 'tcx> {
2020
target_features: &'tcx FxIndexSet<Symbol>,
@@ -511,15 +511,46 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
511511
match ty.kind() {
512512
ty::Error(_) => {}
513513
_ if ty.is_integral() => {}
514+
ty::FnPtr(..) => {
515+
if !self.tcx().features().asm_const_ptr() {
516+
self.tcx()
517+
.sess
518+
.create_feature_err(
519+
AsmConstPtrUnstable { span: op_sp },
520+
sym::asm_const_ptr,
521+
)
522+
.emit();
523+
}
524+
}
525+
ty::RawPtr(pointee, _) | ty::Ref(_, pointee, _)
526+
if self.is_thin_ptr_ty(op_sp, *pointee) =>
527+
{
528+
if !self.tcx().features().asm_const_ptr() {
529+
self.tcx()
530+
.sess
531+
.create_feature_err(
532+
AsmConstPtrUnstable { span: op_sp },
533+
sym::asm_const_ptr,
534+
)
535+
.emit();
536+
}
537+
}
514538
_ => {
539+
let const_possible_ty = if !self.tcx().features().asm_const_ptr() {
540+
"integer"
541+
} else {
542+
"integer or thin pointer"
543+
};
515544
self.fcx
516545
.dcx()
517546
.struct_span_err(op_sp, "invalid type for `const` operand")
518547
.with_span_label(
519548
self.tcx().def_span(anon_const.def_id),
520549
format!("is {} `{}`", ty.kind().article(), ty),
521550
)
522-
.with_help("`const` operands must be of an integer type")
551+
.with_help(format!(
552+
"`const` operands must be of an {const_possible_ty} type"
553+
))
523554
.emit();
524555
}
525556
}

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ symbols! {
474474
as_str,
475475
asm,
476476
asm_const,
477+
asm_const_ptr,
477478
asm_experimental_arch,
478479
asm_experimental_reg,
479480
asm_goto,

tests/ui/asm/const-refs-to-static.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
//@ needs-asm-support
22
//@ ignore-nvptx64
33
//@ ignore-spirv
4+
//@ build-pass
5+
6+
#![feature(asm_const_ptr)]
47

58
use std::arch::{asm, global_asm};
69
use std::ptr::addr_of;
710

811
static FOO: u8 = 42;
912

10-
global_asm!("{}", const addr_of!(FOO));
11-
//~^ ERROR invalid type for `const` operand
13+
global_asm!("/* {} */", const addr_of!(FOO));
1214

1315
#[no_mangle]
1416
fn inline() {
15-
unsafe { asm!("{}", const addr_of!(FOO)) };
16-
//~^ ERROR invalid type for `const` operand
17+
unsafe { asm!("/* {} */", const addr_of!(FOO)) };
1718
}
1819

1920
fn main() {}

tests/ui/asm/const-refs-to-static.stderr

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

tests/ui/asm/invalid-const-operand.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
//@ ignore-nvptx64
33
//@ ignore-spirv
44

5+
#![feature(asm_const_ptr)]
6+
57
use std::arch::{asm, global_asm};
68

79
// Const operands must be integers and must be constants.
@@ -12,7 +14,6 @@ global_asm!("{}", const 0i128);
1214
global_asm!("{}", const 0f32);
1315
//~^ ERROR invalid type for `const` operand
1416
global_asm!("{}", const 0 as *mut u8);
15-
//~^ ERROR invalid type for `const` operand
1617

1718
fn test1() {
1819
unsafe {
@@ -24,8 +25,7 @@ fn test1() {
2425
asm!("{}", const 0f32);
2526
//~^ ERROR invalid type for `const` operand
2627
asm!("{}", const 0 as *mut u8);
27-
//~^ ERROR invalid type for `const` operand
28-
asm!("{}", const &0);
28+
asm!("{}", const b"Foo".as_slice());
2929
//~^ ERROR invalid type for `const` operand
3030
}
3131
}

tests/ui/asm/invalid-const-operand.stderr

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,55 +35,35 @@ LL + const x: /* Type */ = 0;
3535
|
3636

3737
error: invalid type for `const` operand
38-
--> $DIR/invalid-const-operand.rs:12:19
38+
--> $DIR/invalid-const-operand.rs:14:19
3939
|
4040
LL | global_asm!("{}", const 0f32);
4141
| ^^^^^^----
4242
| |
4343
| is an `f32`
4444
|
45-
= help: `const` operands must be of an integer type
46-
47-
error: invalid type for `const` operand
48-
--> $DIR/invalid-const-operand.rs:14:19
49-
|
50-
LL | global_asm!("{}", const 0 as *mut u8);
51-
| ^^^^^^------------
52-
| |
53-
| is a `*mut u8`
54-
|
55-
= help: `const` operands must be of an integer type
45+
= help: `const` operands must be of an integer or thin pointer type
5646

5747
error: invalid type for `const` operand
58-
--> $DIR/invalid-const-operand.rs:24:20
48+
--> $DIR/invalid-const-operand.rs:25:20
5949
|
6050
LL | asm!("{}", const 0f32);
6151
| ^^^^^^----
6252
| |
6353
| is an `f32`
6454
|
65-
= help: `const` operands must be of an integer type
66-
67-
error: invalid type for `const` operand
68-
--> $DIR/invalid-const-operand.rs:26:20
69-
|
70-
LL | asm!("{}", const 0 as *mut u8);
71-
| ^^^^^^------------
72-
| |
73-
| is a `*mut u8`
74-
|
75-
= help: `const` operands must be of an integer type
55+
= help: `const` operands must be of an integer or thin pointer type
7656

7757
error: invalid type for `const` operand
7858
--> $DIR/invalid-const-operand.rs:28:20
7959
|
80-
LL | asm!("{}", const &0);
81-
| ^^^^^^--
60+
LL | asm!("{}", const b"Foo".as_slice());
61+
| ^^^^^^-----------------
8262
| |
83-
| is a `&i32`
63+
| is a `&[u8]`
8464
|
85-
= help: `const` operands must be of an integer type
65+
= help: `const` operands must be of an integer or thin pointer type
8666

87-
error: aborting due to 8 previous errors
67+
error: aborting due to 6 previous errors
8868

8969
For more information about this error, try `rustc --explain E0435`.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ only-x86_64
2+
3+
use std::arch::asm;
4+
5+
fn main() {
6+
unsafe {
7+
asm!("/* {} */", const &0);
8+
//~^ ERROR using pointers in asm `const` operand is experimental
9+
}
10+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0658]: using pointers in asm `const` operand is experimental
2+
--> $DIR/feature-gate-asm_const_ptr.rs:7:26
3+
|
4+
LL | asm!("/* {} */", const &0);
5+
| ^^^^^^^^
6+
|
7+
= note: see issue #128464 <https://github.com/rust-lang/rust/issues/128464> for more information
8+
= help: add `#![feature(asm_const_ptr)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)