Remove support for floating-point constants in asm!
Floating-point constants aren't very useful anyways and this simplifies the code since the type check can now be done in typeck.
This commit is contained in:
parent
36a4d14c7e
commit
f1b11939e2
8 changed files with 70 additions and 91 deletions
|
@ -219,8 +219,6 @@ pub fn asm_const_to_str<'tcx>(
|
||||||
ty::IntTy::I128 => (value as i128).to_string(),
|
ty::IntTy::I128 => (value as i128).to_string(),
|
||||||
ty::IntTy::Isize => unreachable!(),
|
ty::IntTy::Isize => unreachable!(),
|
||||||
},
|
},
|
||||||
ty::Float(ty::FloatTy::F32) => f32::from_bits(value as u32).to_string(),
|
|
||||||
ty::Float(ty::FloatTy::F64) => f64::from_bits(value as u64).to_string(),
|
|
||||||
_ => span_bug!(sp, "asm const has bad type {}", ty_and_layout.ty),
|
_ => span_bug!(sp, "asm const has bad type {}", ty_and_layout.ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,7 +347,7 @@ impl ExprVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) {
|
fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) {
|
||||||
for (idx, (op, op_sp)) in asm.operands.iter().enumerate() {
|
for (idx, (op, _)) in asm.operands.iter().enumerate() {
|
||||||
match *op {
|
match *op {
|
||||||
hir::InlineAsmOperand::In { reg, ref expr } => {
|
hir::InlineAsmOperand::In { reg, ref expr } => {
|
||||||
self.check_asm_operand_type(idx, reg, expr, asm.template, None);
|
self.check_asm_operand_type(idx, reg, expr, asm.template, None);
|
||||||
|
@ -372,19 +372,7 @@ impl ExprVisitor<'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::InlineAsmOperand::Const { ref anon_const } => {
|
hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::Sym { .. } => {}
|
||||||
let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
|
|
||||||
let value = ty::Const::from_anon_const(self.tcx, anon_const_def_id);
|
|
||||||
match value.ty.kind() {
|
|
||||||
ty::Int(_) | ty::Uint(_) | ty::Float(_) => {}
|
|
||||||
_ => {
|
|
||||||
let msg =
|
|
||||||
"asm `const` arguments must be integer or floating-point values";
|
|
||||||
self.tcx.sess.span_err(*op_sp, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::InlineAsmOperand::Sym { .. } => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -405,33 +393,6 @@ impl Visitor<'tcx> for ItemVisitor<'tcx> {
|
||||||
ExprVisitor { tcx: self.tcx, param_env, typeck_results }.visit_body(body);
|
ExprVisitor { tcx: self.tcx, param_env, typeck_results }.visit_body(body);
|
||||||
self.visit_body(body);
|
self.visit_body(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
|
||||||
if let hir::ItemKind::GlobalAsm(asm) = item.kind {
|
|
||||||
for (op, op_sp) in asm.operands {
|
|
||||||
match *op {
|
|
||||||
hir::InlineAsmOperand::Const { ref anon_const } => {
|
|
||||||
let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
|
|
||||||
let value = ty::Const::from_anon_const(self.tcx, anon_const_def_id);
|
|
||||||
match value.ty.kind() {
|
|
||||||
ty::Int(_) | ty::Uint(_) | ty::Float(_) => {}
|
|
||||||
_ => {
|
|
||||||
let msg = "asm `const` arguments must be integer or floating-point values";
|
|
||||||
self.tcx.sess.span_err(*op_sp, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::InlineAsmOperand::In { .. }
|
|
||||||
| hir::InlineAsmOperand::Out { .. }
|
|
||||||
| hir::InlineAsmOperand::InOut { .. }
|
|
||||||
| hir::InlineAsmOperand::SplitInOut { .. }
|
|
||||||
| hir::InlineAsmOperand::Sym { .. } => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
intravisit::walk_item(self, item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visitor<'tcx> for ExprVisitor<'tcx> {
|
impl Visitor<'tcx> for ExprVisitor<'tcx> {
|
||||||
|
|
|
@ -554,10 +554,8 @@ fn typeck_with_fallback<'tcx>(
|
||||||
_ => false,
|
_ => false,
|
||||||
}) =>
|
}) =>
|
||||||
{
|
{
|
||||||
fcx.next_ty_var(TypeVariableOrigin {
|
// Inline assembly constants must be integers.
|
||||||
kind: TypeVariableOriginKind::MiscVariable,
|
fcx.next_int_var()
|
||||||
span,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
_ => fallback(),
|
_ => fallback(),
|
||||||
},
|
},
|
||||||
|
|
|
@ -509,7 +509,7 @@ Several types of operands are supported:
|
||||||
- Identical to `inout` except that the register allocator can reuse a register allocated to an `in` (this can happen if the compiler knows the `in` has the same initial value as the `inlateout`).
|
- Identical to `inout` except that the register allocator can reuse a register allocated to an `in` (this can happen if the compiler knows the `in` has the same initial value as the `inlateout`).
|
||||||
- You should only write to the register after all inputs are read, otherwise you may clobber an input.
|
- You should only write to the register after all inputs are read, otherwise you may clobber an input.
|
||||||
* `const <expr>`
|
* `const <expr>`
|
||||||
- `<expr>` must be an integer or floating-point constant expression.
|
- `<expr>` must be an integer constant expression.
|
||||||
- The value of the expression is formatted as a string and substituted directly into the asm template string.
|
- The value of the expression is formatted as a string and substituted directly into the asm template string.
|
||||||
* `sym <path>`
|
* `sym <path>`
|
||||||
- `<path>` must refer to a `fn` or `static`.
|
- `<path>` must refer to a `fn` or `static`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// only-x86_64
|
// only-x86_64
|
||||||
|
|
||||||
#![feature(asm)]
|
#![feature(asm, global_asm)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -39,5 +39,25 @@ fn main() {
|
||||||
asm!("{}", const const_bar(0));
|
asm!("{}", const const_bar(0));
|
||||||
asm!("{}", const const_bar(x));
|
asm!("{}", const const_bar(x));
|
||||||
//~^ ERROR attempt to use a non-constant value in a constant
|
//~^ ERROR attempt to use a non-constant value in a constant
|
||||||
|
|
||||||
|
// Const operands must be integer and must be constants.
|
||||||
|
|
||||||
|
asm!("{}", const 0);
|
||||||
|
asm!("{}", const 0i32);
|
||||||
|
asm!("{}", const 0i128);
|
||||||
|
asm!("{}", const 0f32);
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
asm!("{}", const 0 as *mut u8);
|
||||||
|
//~^ ERROR mismatched types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Const operands must be integer or floats, and must be constants.
|
||||||
|
|
||||||
|
global_asm!("{}", const 0);
|
||||||
|
global_asm!("{}", const 0i32);
|
||||||
|
global_asm!("{}", const 0i128);
|
||||||
|
global_asm!("{}", const 0f32);
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
global_asm!("{}", const 0 as *mut u8);
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
|
|
@ -64,7 +64,37 @@ LL | asm!("{}", inout(reg) v[..]);
|
||||||
= help: the trait `Sized` is not implemented for `[u64]`
|
= help: the trait `Sized` is not implemented for `[u64]`
|
||||||
= note: all inline asm arguments must have a statically known size
|
= note: all inline asm arguments must have a statically known size
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/type-check-1.rs:48:26
|
||||||
|
|
|
||||||
|
LL | asm!("{}", const 0f32);
|
||||||
|
| ^^^^ expected integer, found `f32`
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0435.
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/type-check-1.rs:50:26
|
||||||
|
|
|
||||||
|
LL | asm!("{}", const 0 as *mut u8);
|
||||||
|
| ^^^^^^^^^^^^ expected integer, found *-ptr
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found raw pointer `*mut u8`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/type-check-1.rs:60:25
|
||||||
|
|
|
||||||
|
LL | global_asm!("{}", const 0f32);
|
||||||
|
| ^^^^ expected integer, found `f32`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/type-check-1.rs:62:25
|
||||||
|
|
|
||||||
|
LL | global_asm!("{}", const 0 as *mut u8);
|
||||||
|
| ^^^^^^^^^^^^ expected integer, found *-ptr
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found raw pointer `*mut u8`
|
||||||
|
|
||||||
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0277, E0308, E0435.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// only-x86_64
|
// only-x86_64
|
||||||
|
|
||||||
#![feature(asm, global_asm, repr_simd, never_type)]
|
#![feature(asm, repr_simd, never_type)]
|
||||||
|
|
||||||
#[repr(simd)]
|
#[repr(simd)]
|
||||||
struct SimdNonCopy(f32, f32, f32, f32);
|
struct SimdNonCopy(f32, f32, f32, f32);
|
||||||
|
@ -26,14 +26,6 @@ fn main() {
|
||||||
asm!("{}", inout(reg) v[0]);
|
asm!("{}", inout(reg) v[0]);
|
||||||
//~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
|
//~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
|
||||||
|
|
||||||
// Const operands must be integer or floats, and must be constants.
|
|
||||||
|
|
||||||
asm!("{}", const 0);
|
|
||||||
asm!("{}", const 0i32);
|
|
||||||
asm!("{}", const 0f32);
|
|
||||||
asm!("{}", const 0 as *mut u8);
|
|
||||||
//~^ ERROR asm `const` arguments must be integer or floating-point values
|
|
||||||
|
|
||||||
// This currently causes an ICE: https://github.com/rust-lang/rust/issues/81857
|
// This currently causes an ICE: https://github.com/rust-lang/rust/issues/81857
|
||||||
// asm!("{}", const &0);
|
// asm!("{}", const &0);
|
||||||
// ERROR asm `const` arguments must be integer or floating-point values
|
// ERROR asm `const` arguments must be integer or floating-point values
|
||||||
|
@ -90,11 +82,3 @@ fn main() {
|
||||||
asm!("{}", in(reg) u);
|
asm!("{}", in(reg) u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Const operands must be integer or floats, and must be constants.
|
|
||||||
|
|
||||||
global_asm!("{}", const 0);
|
|
||||||
global_asm!("{}", const 0i32);
|
|
||||||
global_asm!("{}", const 0f32);
|
|
||||||
global_asm!("{}", const 0 as *mut u8);
|
|
||||||
//~^ ERROR asm `const` arguments must be integer or floating-point values
|
|
||||||
|
|
|
@ -1,19 +1,13 @@
|
||||||
error: asm `const` arguments must be integer or floating-point values
|
|
||||||
--> $DIR/type-check-2.rs:34:20
|
|
||||||
|
|
|
||||||
LL | asm!("{}", const 0 as *mut u8);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: arguments for inline assembly must be copyable
|
error: arguments for inline assembly must be copyable
|
||||||
--> $DIR/type-check-2.rs:54:32
|
--> $DIR/type-check-2.rs:46:32
|
||||||
|
|
|
|
||||||
LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
|
LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `SimdNonCopy` does not implement the Copy trait
|
= note: `SimdNonCopy` does not implement the Copy trait
|
||||||
|
|
||||||
error: cannot use value of type `[closure@$DIR/type-check-2.rs:66:28: 66:38]` for inline assembly
|
error: cannot use value of type `[closure@$DIR/type-check-2.rs:58:28: 58:38]` for inline assembly
|
||||||
--> $DIR/type-check-2.rs:66:28
|
--> $DIR/type-check-2.rs:58:28
|
||||||
|
|
|
|
||||||
LL | asm!("{}", in(reg) |x: i32| x);
|
LL | asm!("{}", in(reg) |x: i32| x);
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
@ -21,7 +15,7 @@ LL | asm!("{}", in(reg) |x: i32| x);
|
||||||
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
||||||
|
|
||||||
error: cannot use value of type `Vec<i32>` for inline assembly
|
error: cannot use value of type `Vec<i32>` for inline assembly
|
||||||
--> $DIR/type-check-2.rs:68:28
|
--> $DIR/type-check-2.rs:60:28
|
||||||
|
|
|
|
||||||
LL | asm!("{}", in(reg) vec![0]);
|
LL | asm!("{}", in(reg) vec![0]);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
@ -30,7 +24,7 @@ LL | asm!("{}", in(reg) vec![0]);
|
||||||
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: cannot use value of type `(i32, i32, i32)` for inline assembly
|
error: cannot use value of type `(i32, i32, i32)` for inline assembly
|
||||||
--> $DIR/type-check-2.rs:70:28
|
--> $DIR/type-check-2.rs:62:28
|
||||||
|
|
|
|
||||||
LL | asm!("{}", in(reg) (1, 2, 3));
|
LL | asm!("{}", in(reg) (1, 2, 3));
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -38,7 +32,7 @@ LL | asm!("{}", in(reg) (1, 2, 3));
|
||||||
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
||||||
|
|
||||||
error: cannot use value of type `[i32; 3]` for inline assembly
|
error: cannot use value of type `[i32; 3]` for inline assembly
|
||||||
--> $DIR/type-check-2.rs:72:28
|
--> $DIR/type-check-2.rs:64:28
|
||||||
|
|
|
|
||||||
LL | asm!("{}", in(reg) [1, 2, 3]);
|
LL | asm!("{}", in(reg) [1, 2, 3]);
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -46,7 +40,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]);
|
||||||
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
||||||
|
|
||||||
error: cannot use value of type `fn() {main}` for inline assembly
|
error: cannot use value of type `fn() {main}` for inline assembly
|
||||||
--> $DIR/type-check-2.rs:80:31
|
--> $DIR/type-check-2.rs:72:31
|
||||||
|
|
|
|
||||||
LL | asm!("{}", inout(reg) f);
|
LL | asm!("{}", inout(reg) f);
|
||||||
| ^
|
| ^
|
||||||
|
@ -54,27 +48,21 @@ LL | asm!("{}", inout(reg) f);
|
||||||
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
||||||
|
|
||||||
error: cannot use value of type `&mut i32` for inline assembly
|
error: cannot use value of type `&mut i32` for inline assembly
|
||||||
--> $DIR/type-check-2.rs:83:31
|
--> $DIR/type-check-2.rs:75:31
|
||||||
|
|
|
|
||||||
LL | asm!("{}", inout(reg) r);
|
LL | asm!("{}", inout(reg) r);
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
||||||
|
|
||||||
error: asm `const` arguments must be integer or floating-point values
|
|
||||||
--> $DIR/type-check-2.rs:99:19
|
|
||||||
|
|
|
||||||
LL | global_asm!("{}", const 0 as *mut u8);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: asm `sym` operand must point to a fn or static
|
error: asm `sym` operand must point to a fn or static
|
||||||
--> $DIR/type-check-2.rs:47:24
|
--> $DIR/type-check-2.rs:39:24
|
||||||
|
|
|
|
||||||
LL | asm!("{}", sym C);
|
LL | asm!("{}", sym C);
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: asm `sym` operand must point to a fn or static
|
error: asm `sym` operand must point to a fn or static
|
||||||
--> $DIR/type-check-2.rs:49:24
|
--> $DIR/type-check-2.rs:41:24
|
||||||
|
|
|
|
||||||
LL | asm!("{}", sym x);
|
LL | asm!("{}", sym x);
|
||||||
| ^
|
| ^
|
||||||
|
@ -109,7 +97,7 @@ LL | let v: Vec<u64> = vec![0, 1, 2];
|
||||||
LL | asm!("{}", inout(reg) v[0]);
|
LL | asm!("{}", inout(reg) v[0]);
|
||||||
| ^ cannot borrow as mutable
|
| ^ cannot borrow as mutable
|
||||||
|
|
||||||
error: aborting due to 15 previous errors
|
error: aborting due to 13 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0381, E0596.
|
Some errors have detailed explanations: E0381, E0596.
|
||||||
For more information about an error, try `rustc --explain E0381`.
|
For more information about an error, try `rustc --explain E0381`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue