1
Fork 0

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:
Amanieu d'Antras 2021-04-29 00:59:15 +01:00
parent 36a4d14c7e
commit f1b11939e2
8 changed files with 70 additions and 91 deletions

View file

@ -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),
} }
} }

View file

@ -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> {

View file

@ -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(),
}, },

View file

@ -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`.

View file

@ -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

View file

@ -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`.

View file

@ -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

View file

@ -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`.