Skip to content

Commit 085397e

Browse files
committed
Implement asm_const_ptr feature
The backend now fully supports codegen of const pointers, remove the block inside typeck behind a new feature gate. Tests are also added.
1 parent bd63eb5 commit 085397e

File tree

13 files changed

+144
-65
lines changed

13 files changed

+144
-65
lines changed

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,8 @@ declare_features! (
384384
(unstable, arbitrary_self_types, "1.23.0", Some(44874)),
385385
/// Allows inherent and trait methods with arbitrary self types that are raw pointers.
386386
(unstable, arbitrary_self_types_pointers, "1.83.0", Some(44874)),
387+
/// Allows using `const` operands with pointer in inline assembly.
388+
(unstable, asm_const_ptr, "CURRENT_RUSTC_VERSION", Some(128464)),
387389
/// Enables experimental inline assembly support for additional architectures.
388390
(unstable, asm_experimental_arch, "1.58.0", Some(93335)),
389391
/// 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
@@ -15,6 +15,10 @@ hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but
1515
.note = we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new
1616
1717
hir_typeck_as_deref_suggestion = consider using `as_deref` here
18+
19+
hir_typeck_asm_const_ptr_unstable =
20+
using pointers in asm `const` operand is experimental
21+
1822
hir_typeck_base_expression_double_dot = base expression required after `..`
1923
hir_typeck_base_expression_double_dot_add_expr = add a base expression here
2024
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
@@ -19,6 +19,13 @@ use rustc_span::{Ident, Span, Symbol};
1919

2020
use crate::{FnCtxt, fluent_generated as fluent};
2121

22+
#[derive(Diagnostic)]
23+
#[diag(hir_typeck_asm_const_ptr_unstable)]
24+
pub(crate) struct AsmConstPtrUnstable {
25+
#[primary_span]
26+
pub span: Span,
27+
}
28+
2229
#[derive(Diagnostic)]
2330
#[diag(hir_typeck_base_expression_double_dot, code = E0797)]
2431
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>,
@@ -522,15 +522,46 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
522522
match ty.kind() {
523523
ty::Error(_) => {}
524524
_ if ty.is_integral() => {}
525+
ty::FnPtr(..) => {
526+
if !self.tcx().features().asm_const_ptr() {
527+
self.tcx()
528+
.sess
529+
.create_feature_err(
530+
AsmConstPtrUnstable { span: op_sp },
531+
sym::asm_const_ptr,
532+
)
533+
.emit();
534+
}
535+
}
536+
ty::RawPtr(pointee, _) | ty::Ref(_, pointee, _)
537+
if self.is_thin_ptr_ty(op_sp, *pointee) =>
538+
{
539+
if !self.tcx().features().asm_const_ptr() {
540+
self.tcx()
541+
.sess
542+
.create_feature_err(
543+
AsmConstPtrUnstable { span: op_sp },
544+
sym::asm_const_ptr,
545+
)
546+
.emit();
547+
}
548+
}
525549
_ => {
550+
let const_possible_ty = if !self.tcx().features().asm_const_ptr() {
551+
"integer"
552+
} else {
553+
"integer or thin pointer"
554+
};
526555
self.fcx
527556
.dcx()
528557
.struct_span_err(op_sp, "invalid type for `const` operand")
529558
.with_span_label(
530559
self.tcx().def_span(anon_const.def_id),
531560
format!("is {} `{}`", ty.kind().article(), ty),
532561
)
533-
.with_help("`const` operands must be of an integer type")
562+
.with_help(format!(
563+
"`const` operands must be of an {const_possible_ty} type"
564+
))
534565
.emit();
535566
}
536567
}

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ symbols! {
481481
asm,
482482
asm_cfg,
483483
asm_const,
484+
asm_const_ptr,
484485
asm_experimental_arch,
485486
asm_experimental_reg,
486487
asm_goto,

tests/assembly-llvm/asm/global_asm.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//@ compile-flags: -C symbol-mangling-version=v0
66

77
#![crate_type = "rlib"]
8+
#![feature(asm_const_ptr)]
89

910
use std::arch::global_asm;
1011

@@ -26,6 +27,10 @@ global_asm!("call {}", sym my_func);
2627
global_asm!("lea rax, [rip + {}]", sym MY_STATIC);
2728
// CHECK: call _RNvC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_10global_asm6foobar
2829
global_asm!("call {}", sym foobar);
30+
// CHECK: lea rax, [rip + _RNKNaC[[CRATE_IDENT]]_10global_asms4_00B3_]
31+
global_asm!("lea rax, [rip + {}]", const &1);
32+
// CHECK: lea rax, [rip + _RNKNaC[[CRATE_IDENT]]_10global_asms5_00B3_+4]
33+
global_asm!("lea rax, [rip + {}]", const &[1; 2][1]);
2934
// CHECK: _RNvC[[CRATE_IDENT]]_10global_asm6foobar:
3035
fn foobar() {
3136
loop {}

tests/assembly-llvm/asm/x86-types.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//@ compile-flags: -C target-feature=+avx512bw
1010
//@ compile-flags: -Zmerge-functions=disabled
1111

12-
#![feature(no_core, repr_simd, f16, f128)]
12+
#![feature(no_core, repr_simd, f16, f128, asm_const_ptr)]
1313
#![crate_type = "rlib"]
1414
#![no_core]
1515
#![allow(asm_sub_register, non_camel_case_types)]
@@ -101,6 +101,15 @@ pub unsafe fn sym_static() {
101101
asm!("mov al, byte ptr [{}]", sym extern_static);
102102
}
103103

104+
// CHECK-LABEL: const_ptr:
105+
// CHECK: #APP
106+
// CHECK: mov al, byte ptr [{{.*}}anon{{.*}}]
107+
// CHECK: #NO_APP
108+
#[no_mangle]
109+
pub unsafe fn const_ptr() {
110+
asm!("mov al, byte ptr [{}]", const &1u8);
111+
}
112+
104113
macro_rules! check {
105114
($func:ident $ty:ident $class:ident $mov:literal) => {
106115
#[no_mangle]
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: 9 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,21 +14,25 @@ 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 {
19-
// Const operands must be integers and must be constants.
20+
// Const operands must be integers or thin pointers
2021

2122
asm!("{}", const 0);
2223
asm!("{}", const 0i32);
2324
asm!("{}", const 0i128);
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
2828
asm!("{}", const &0);
29+
asm!("{}", const b"Foo".as_slice());
2930
//~^ ERROR invalid type for `const` operand
31+
32+
asm!("{}", const test1 as fn());
33+
asm!("{}", const test1);
34+
asm!("{}", const (|| {}) as fn());
35+
asm!("{}", const || {});
3036
}
3137
}
3238

0 commit comments

Comments
 (0)