From 7e4aaeceb31a3046c7a7c7d8f800aa997494e254 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 3 May 2023 18:43:27 -0400 Subject: [PATCH] Add a stable flag to control codegen UB checks --- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_mir_transform/src/check_alignment.rs | 2 +- compiler/rustc_session/src/options.rs | 2 ++ compiler/rustc_session/src/session.rs | 4 ++++ src/doc/rustc/src/codegen-options/index.md | 11 +++++++++++ src/tools/miri/src/lib.rs | 2 +- .../miri/tests/fail/unaligned_pointers/alignment.rs | 1 - .../tests/fail/unaligned_pointers/atomic_unaligned.rs | 2 +- .../tests/fail/unaligned_pointers/drop_in_place.rs | 2 -- .../tests/fail/unaligned_pointers/dyn_alignment.rs | 2 +- .../unaligned_pointers/intptrcast_alignment_check.rs | 2 +- .../fail/unaligned_pointers/reference_to_packed.rs | 2 +- .../tests/fail/unaligned_pointers/unaligned_ptr1.rs | 2 +- .../tests/fail/unaligned_pointers/unaligned_ptr2.rs | 2 +- .../tests/fail/unaligned_pointers/unaligned_ptr3.rs | 2 +- .../tests/fail/unaligned_pointers/unaligned_ptr4.rs | 2 +- .../fail/unaligned_pointers/unaligned_ptr_zst.rs | 2 +- .../fail/unaligned_pointers/unaligned_ref_addr_of.rs | 2 +- src/tools/miri/tests/pass/disable-alignment-check.rs | 2 +- 19 files changed, 31 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index ec4fd78994e95..a06a0cfbe8504 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -609,6 +609,7 @@ fn test_codegen_options_tracking_hash() { tracked!(debug_assertions, Some(true)); tracked!(debuginfo, DebugInfo::Limited); tracked!(embed_bitcode, false); + tracked!(extra_ub_checks, Some(true)); tracked!(force_frame_pointers, Some(false)); tracked!(force_unwind_tables, Some(true)); tracked!(inline_threshold, Some(0xf007ba11)); diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index 28765af20ad3b..d75fb59d8499e 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -18,7 +18,7 @@ impl<'tcx> MirPass<'tcx> for CheckAlignment { if sess.target.llvm_target == "i686-pc-windows-msvc" { return false; } - sess.opts.debug_assertions + sess.extra_ub_checks() } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 11fbd9f8f86a0..07c39df6a514f 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1316,6 +1316,8 @@ options! { "emit bitcode in rlibs (default: yes)"), extra_filename: String = (String::new(), parse_string, [UNTRACKED], "extra data to put in each output filename"), + extra_ub_checks: Option = (None, parse_opt_bool, [TRACKED], + "insert extra runtime checks in codegen that catch Undefined Behavior"), force_frame_pointers: Option = (None, parse_opt_bool, [TRACKED], "force use of the frame pointers"), #[rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field")] diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 5cac11cc8f782..1d228627f07d9 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1104,6 +1104,10 @@ impl Session { self.opts.cg.overflow_checks.unwrap_or(self.opts.debug_assertions) } + pub fn extra_ub_checks(&self) -> bool { + self.opts.cg.extra_ub_checks.unwrap_or(self.opts.debug_assertions) + } + pub fn relocation_model(&self) -> RelocModel { self.opts.cg.relocation_model.unwrap_or(self.target.relocation_model) } diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index cfbe1e09cde0c..255c9cca0fc5f 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -140,6 +140,17 @@ This option allows you to put extra data in each output filename. It takes a string to add as a suffix to the filename. See the [`--emit` flag][option-emit] for more information. +## extra-ub-checks + +This flag controls whether the compiler inserts runtime checks during code generation +to catch Undefined Behavior. + +* `y`, `yes`, `on`, `true`, or no value: insert such checks regardless of debug-assertions. +* `n`, `no`, `off`, `false`: do not emit such checks regardless of debug-assertions. + +If not specified, extra UB checks are enabled if +[debug-assertions](#debug-assertions) are enabled, disabled otherwise. + ## force-frame-pointers This flag forces the use of frame pointers. It takes one of the following diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index f1d8ce01bc24c..a319154677fc8 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -138,5 +138,5 @@ pub const MIRI_DEFAULT_ARGS: &[&str] = &[ "-Zmir-emit-retag", "-Zmir-keep-place-mention", "-Zmir-opt-level=0", - "-Zmir-enable-passes=-CheckAlignment", + "-Cextra-ub-checks=false", ]; diff --git a/src/tools/miri/tests/fail/unaligned_pointers/alignment.rs b/src/tools/miri/tests/fail/unaligned_pointers/alignment.rs index 6bb95ae4bcb33..438e74e5b8d52 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/alignment.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/alignment.rs @@ -1,5 +1,4 @@ //@normalize-stderr-test: "\| +\^+" -> "| ^" -//@compile-flags: -Cdebug-assertions=no fn main() { // No retry needed, this fails reliably. diff --git a/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs b/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs index 29976836b0ba6..9dd652fd8217a 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs @@ -1,4 +1,4 @@ -//@compile-flags: -Zmiri-symbolic-alignment-check -Cdebug-assertions=no +//@compile-flags: -Zmiri-symbolic-alignment-check #![feature(core_intrinsics)] fn main() { diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs index d71d5954a40c7..95f1065a08def 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs @@ -1,5 +1,3 @@ -//@compile-flags: -Cdebug-assertions=no - #[repr(transparent)] struct HasDrop(u8); diff --git a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs index b5a9b2bf18ee3..f455df3686eeb 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs @@ -1,5 +1,5 @@ // should find the bug even without, but gets masked by optimizations -//@compile-flags: -Zmiri-disable-stacked-borrows -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-stacked-borrows //@normalize-stderr-test: "but found [0-9]+" -> "but found $$ALIGN" #[repr(align(256))] diff --git a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs index 11f63839122d6..63d617cd17e18 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs @@ -1,4 +1,4 @@ -//@compile-flags: -Zmiri-symbolic-alignment-check -Zmiri-permissive-provenance -Cdebug-assertions=no +//@compile-flags: -Zmiri-symbolic-alignment-check -Zmiri-permissive-provenance // With the symbolic alignment check, even with intptrcast and without // validation, we want to be *sure* to catch bugs that arise from pointers being // insufficiently aligned. The only way to achieve that is not to let programs diff --git a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs index b9d29d775ab84..2084674dcca53 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs @@ -1,5 +1,5 @@ // This should fail even without SB -//@compile-flags: -Zmiri-disable-stacked-borrows -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-stacked-borrows #![allow(dead_code, unused_variables)] diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs index 9c72781ee050c..6ceca6c6bc2e7 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs @@ -1,5 +1,5 @@ // This should fail even without validation or Stacked Borrows. -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows fn main() { // Try many times as this might work by chance. diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs index ac3062773deea..e8cec11fb7db0 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs @@ -1,5 +1,5 @@ // This should fail even without validation or Stacked Borrows. -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows fn main() { // No retry needed, this fails reliably. diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.rs index a7fcf30c6ea0a..3aa8cb492a13c 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.rs @@ -1,5 +1,5 @@ // This should fail even without validation or Stacked Borrows. -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows fn main() { // Try many times as this might work by chance. diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.rs index b8b01e113c960..606316120d6e4 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.rs @@ -1,5 +1,5 @@ // This should fail even without validation or Stacked Borrows. -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows fn main() { // Make sure we notice when a u16 is loaded at offset 1 into a u8 allocation. diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs index 289536287a90e..0bfa5fd390bc5 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs @@ -1,5 +1,5 @@ // This should fail even without validation -//@compile-flags: -Zmiri-disable-validation -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-validation fn main() { // Try many times as this might work by chance. diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs index 470420acd5084..e4f80b23b4a2d 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs @@ -1,5 +1,5 @@ // This should fail even without Stacked Borrows. -//@compile-flags: -Zmiri-disable-stacked-borrows -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-stacked-borrows fn main() { // Try many times as this might work by chance. diff --git a/src/tools/miri/tests/pass/disable-alignment-check.rs b/src/tools/miri/tests/pass/disable-alignment-check.rs index e8c0e027673c2..fdcacc6cea41c 100644 --- a/src/tools/miri/tests/pass/disable-alignment-check.rs +++ b/src/tools/miri/tests/pass/disable-alignment-check.rs @@ -1,6 +1,6 @@ //@revisions: stack tree //@[tree]compile-flags: -Zmiri-tree-borrows -//@compile-flags: -Zmiri-disable-alignment-check -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-alignment-check fn main() { let mut x = [0u8; 20];