From 65a985e81e05bef484589fbb45dcee8e8048cda5 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Apr 2020 16:03:35 -0700 Subject: [PATCH 1/6] Check for `llvm_asm` in a const context --- src/librustc_mir/transform/check_consts/ops.rs | 4 ++++ src/librustc_mir/transform/check_consts/validation.rs | 5 ++++- src/test/ui/consts/inline_asm.rs | 6 ++++++ src/test/ui/consts/inline_asm.stderr | 9 +++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/consts/inline_asm.rs create mode 100644 src/test/ui/consts/inline_asm.stderr diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs index b5e62aa20130b..c4b94b70938d3 100644 --- a/src/librustc_mir/transform/check_consts/ops.rs +++ b/src/librustc_mir/transform/check_consts/ops.rs @@ -147,6 +147,10 @@ impl NonConstOp for IfOrMatch { } } +#[derive(Debug)] +pub struct InlineAsm; +impl NonConstOp for InlineAsm {} + #[derive(Debug)] pub struct LiveDrop; impl NonConstOp for LiveDrop { diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index cee98e9b299c1..19df6e39e4c24 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -481,11 +481,14 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) => { self.check_op(ops::IfOrMatch); } + StatementKind::LlvmInlineAsm { .. } => { + self.check_op(ops::InlineAsm); + } + // FIXME(eddyb) should these really do nothing? StatementKind::FakeRead(..) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) - | StatementKind::LlvmInlineAsm { .. } | StatementKind::Retag { .. } | StatementKind::AscribeUserType(..) | StatementKind::Nop => {} diff --git a/src/test/ui/consts/inline_asm.rs b/src/test/ui/consts/inline_asm.rs new file mode 100644 index 0000000000000..c2ab97e54f0c8 --- /dev/null +++ b/src/test/ui/consts/inline_asm.rs @@ -0,0 +1,6 @@ +#![feature(llvm_asm)] + +const _: () = unsafe { llvm_asm!("nop") }; +//~^ ERROR contains unimplemented expression type + +fn main() {} diff --git a/src/test/ui/consts/inline_asm.stderr b/src/test/ui/consts/inline_asm.stderr new file mode 100644 index 0000000000000..68a78d6175f6b --- /dev/null +++ b/src/test/ui/consts/inline_asm.stderr @@ -0,0 +1,9 @@ +error[E0019]: constant contains unimplemented expression type + --> $DIR/inline_asm.rs:3:1 + | +LL | const _: () = unsafe { llvm_asm!("nop") }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0019`. From e59000265252667c66ed93c85ff21713ac4d172a Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Apr 2020 16:05:59 -0700 Subject: [PATCH 2/6] Exhaustively match on `StatementKind` during const checking --- src/librustc_mir/transform/check_consts/validation.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 19df6e39e4c24..67110a3aed46d 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -478,15 +478,20 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { StatementKind::Assign(..) | StatementKind::SetDiscriminant { .. } => { self.super_statement(statement, location); } - StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) => { + + StatementKind::FakeRead( + FakeReadCause::ForMatchedPlace + | FakeReadCause::ForMatchGuard + | FakeReadCause::ForGuardBinding, + _, + ) => { self.check_op(ops::IfOrMatch); } StatementKind::LlvmInlineAsm { .. } => { self.check_op(ops::InlineAsm); } - // FIXME(eddyb) should these really do nothing? - StatementKind::FakeRead(..) + StatementKind::FakeRead(FakeReadCause::ForLet | FakeReadCause::ForIndex, _) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Retag { .. } From d24e39bb910e671e1eab27df0aef37985f58df2a Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Apr 2020 16:06:33 -0700 Subject: [PATCH 3/6] Exhaustively match on `TerminatorKind` during const checking --- .../transform/check_consts/validation.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 67110a3aed46d..d2d5e95a1de99 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -580,7 +580,17 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } } - _ => {} + TerminatorKind::Abort + | TerminatorKind::Assert { .. } + | TerminatorKind::FalseEdges { .. } + | TerminatorKind::FalseUnwind { .. } + | TerminatorKind::GeneratorDrop + | TerminatorKind::Goto { .. } + | TerminatorKind::Resume + | TerminatorKind::Return + | TerminatorKind::SwitchInt { .. } + | TerminatorKind::Unreachable + | TerminatorKind::Yield { .. } => {} } } } From e5b58b089ed94a91581a44d0b6d670f18517ff34 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Apr 2020 16:20:06 -0700 Subject: [PATCH 4/6] Note that some terminators should cause an error --- src/librustc_mir/transform/check_consts/validation.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index d2d5e95a1de99..b1cc7edc77432 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -580,6 +580,8 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } } + // FIXME: Some of these are only caught by `min_const_fn`, but should error here + // instead. TerminatorKind::Abort | TerminatorKind::Assert { .. } | TerminatorKind::FalseEdges { .. } From 79543397d70c15991dfc56fb4f89988326d4fcf3 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Apr 2020 17:53:17 -0700 Subject: [PATCH 5/6] Bless new miri_unleashed test --- src/test/ui/consts/miri_unleashed/inline_asm.rs | 2 +- src/test/ui/consts/miri_unleashed/inline_asm.stderr | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/test/ui/consts/miri_unleashed/inline_asm.rs b/src/test/ui/consts/miri_unleashed/inline_asm.rs index f56131025627b..f5be75431bae7 100644 --- a/src/test/ui/consts/miri_unleashed/inline_asm.rs +++ b/src/test/ui/consts/miri_unleashed/inline_asm.rs @@ -6,7 +6,7 @@ fn main() {} // Make sure we catch executing inline assembly. -static TEST_BAD: () = { +static TEST_BAD: () = { //~ WARN: skipping const checks unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } //~^ ERROR could not evaluate static initializer //~| NOTE in this expansion of llvm_asm! diff --git a/src/test/ui/consts/miri_unleashed/inline_asm.stderr b/src/test/ui/consts/miri_unleashed/inline_asm.stderr index 3cbdd326c8233..ef11c5b1d1ab8 100644 --- a/src/test/ui/consts/miri_unleashed/inline_asm.stderr +++ b/src/test/ui/consts/miri_unleashed/inline_asm.stderr @@ -1,3 +1,14 @@ +warning: skipping const checks + --> $DIR/inline_asm.rs:9:1 + | +LL | / static TEST_BAD: () = { +LL | | unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } +LL | | +LL | | +LL | | +LL | | }; + | |__^ + error[E0080]: could not evaluate static initializer --> $DIR/inline_asm.rs:10:14 | @@ -6,6 +17,6 @@ LL | unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0080`. From 152c06569b6d785cea2d408c3ebd93aaee09772d Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 21 Apr 2020 09:24:41 -0700 Subject: [PATCH 6/6] Assign correct span to new illegal ops --- .../transform/check_consts/validation.rs | 2 ++ src/test/ui/consts/inline_asm.stderr | 6 ++++-- src/test/ui/consts/miri_unleashed/inline_asm.rs | 4 +++- src/test/ui/consts/miri_unleashed/inline_asm.stderr | 13 +++++-------- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index b1cc7edc77432..231b3be89826b 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -485,9 +485,11 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { | FakeReadCause::ForGuardBinding, _, ) => { + self.super_statement(statement, location); self.check_op(ops::IfOrMatch); } StatementKind::LlvmInlineAsm { .. } => { + self.super_statement(statement, location); self.check_op(ops::InlineAsm); } diff --git a/src/test/ui/consts/inline_asm.stderr b/src/test/ui/consts/inline_asm.stderr index 68a78d6175f6b..0a064c8136651 100644 --- a/src/test/ui/consts/inline_asm.stderr +++ b/src/test/ui/consts/inline_asm.stderr @@ -1,8 +1,10 @@ error[E0019]: constant contains unimplemented expression type - --> $DIR/inline_asm.rs:3:1 + --> $DIR/inline_asm.rs:3:24 | LL | const _: () = unsafe { llvm_asm!("nop") }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/miri_unleashed/inline_asm.rs b/src/test/ui/consts/miri_unleashed/inline_asm.rs index f5be75431bae7..ddc4767b83aa1 100644 --- a/src/test/ui/consts/miri_unleashed/inline_asm.rs +++ b/src/test/ui/consts/miri_unleashed/inline_asm.rs @@ -6,9 +6,11 @@ fn main() {} // Make sure we catch executing inline assembly. -static TEST_BAD: () = { //~ WARN: skipping const checks +static TEST_BAD: () = { unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } //~^ ERROR could not evaluate static initializer //~| NOTE in this expansion of llvm_asm! //~| NOTE inline assembly is not supported + //~| WARN skipping const checks + //~| NOTE in this expansion of llvm_asm! }; diff --git a/src/test/ui/consts/miri_unleashed/inline_asm.stderr b/src/test/ui/consts/miri_unleashed/inline_asm.stderr index ef11c5b1d1ab8..444a0172621e2 100644 --- a/src/test/ui/consts/miri_unleashed/inline_asm.stderr +++ b/src/test/ui/consts/miri_unleashed/inline_asm.stderr @@ -1,13 +1,10 @@ warning: skipping const checks - --> $DIR/inline_asm.rs:9:1 + --> $DIR/inline_asm.rs:10:14 + | +LL | unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -LL | / static TEST_BAD: () = { -LL | | unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } -LL | | -LL | | -LL | | -LL | | }; - | |__^ + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: could not evaluate static initializer --> $DIR/inline_asm.rs:10:14