]> git.lizzy.rs Git - rust.git/commitdiff
Move alignment failure error reporting to machine
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Tue, 22 Nov 2022 11:16:33 +0000 (11:16 +0000)
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Thu, 15 Dec 2022 16:07:35 +0000 (16:07 +0000)
compiler/rustc_const_eval/src/const_eval/machine.rs
compiler/rustc_const_eval/src/interpret/machine.rs
compiler/rustc_const_eval/src/interpret/memory.rs
compiler/rustc_mir_transform/src/const_prop.rs
compiler/rustc_mir_transform/src/dataflow_const_prop.rs
src/tools/miri/src/machine.rs

index 355ad66929629477617bc9fe4c005615860bd231..50776d65551ef48d6d3b09d9f796047c06caaf62 100644 (file)
@@ -1,9 +1,10 @@
 use rustc_hir::def::DefKind;
-use rustc_hir::LangItem;
+use rustc_hir::{LangItem, CRATE_HIR_ID};
 use rustc_middle::mir;
-use rustc_middle::mir::interpret::PointerArithmetic;
+use rustc_middle::mir::interpret::{PointerArithmetic, UndefinedBehaviorInfo};
 use rustc_middle::ty::layout::FnAbiOf;
 use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_session::lint::builtin::INVALID_ALIGNMENT;
 use std::borrow::Borrow;
 use std::hash::Hash;
 use std::ops::ControlFlow;
@@ -338,6 +339,40 @@ fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
         ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
     }
 
+    fn alignment_check_failed(
+        ecx: &InterpCx<'mir, 'tcx, Self>,
+        has: Align,
+        required: Align,
+        check: CheckAlignment,
+    ) -> InterpResult<'tcx, ()> {
+        match check {
+            CheckAlignment::Error => {
+                throw_ub!(AlignmentCheckFailed { has, required })
+            }
+            CheckAlignment::No => span_bug!(
+                ecx.cur_span(),
+                "`alignment_check_failed` called when no alignment check requested"
+            ),
+            CheckAlignment::FutureIncompat => ecx.tcx.struct_span_lint_hir(
+                INVALID_ALIGNMENT,
+                ecx.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID),
+                ecx.cur_span(),
+                UndefinedBehaviorInfo::AlignmentCheckFailed { has, required }.to_string(),
+                |db| {
+                    let mut stacktrace = ecx.generate_stacktrace();
+                    // Filter out `requires_caller_location` frames.
+                    stacktrace
+                        .retain(|frame| !frame.instance.def.requires_caller_location(*ecx.tcx));
+                    for frame in stacktrace {
+                        db.span_label(frame.span, format!("inside `{}`", frame.instance));
+                    }
+                    db
+                },
+            ),
+        }
+        Ok(())
+    }
+
     fn load_mir(
         ecx: &InterpCx<'mir, 'tcx, Self>,
         instance: ty::InstanceDef<'tcx>,
index f52545317ea1a48fca2f750fb7aaf3ca9fd6831f..1d4ef20d0651f7bd11d7cb466f0290d375ff27d8 100644 (file)
@@ -10,7 +10,7 @@
 use rustc_middle::mir;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::def_id::DefId;
-use rustc_target::abi::Size;
+use rustc_target::abi::{Align, Size};
 use rustc_target::spec::abi::Abi as CallAbi;
 
 use crate::const_eval::CheckAlignment;
@@ -132,6 +132,13 @@ pub trait Machine<'mir, 'tcx>: Sized {
     /// If this returns true, Provenance::OFFSET_IS_ADDR must be true.
     fn use_addr_for_alignment_check(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
 
+    fn alignment_check_failed(
+        ecx: &InterpCx<'mir, 'tcx, Self>,
+        has: Align,
+        required: Align,
+        check: CheckAlignment,
+    ) -> InterpResult<'tcx, ()>;
+
     /// Whether to enforce the validity invariant
     fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
 
index ffd5e05bcc40aa678811a63877e2d697404920ee..5b1ac6b2f65e29f7bc7a726d3044a6fd5cb95654 100644 (file)
 
 use rustc_ast::Mutability;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_hir::CRATE_HIR_ID;
 use rustc_middle::mir::display_allocation;
-use rustc_middle::mir::interpret::UndefinedBehaviorInfo;
 use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
-use rustc_session::lint::builtin::INVALID_ALIGNMENT;
 use rustc_target::abi::{Align, HasDataLayout, Size};
 
 use crate::const_eval::CheckAlignment;
@@ -448,7 +445,7 @@ fn check_and_deref_ptr<T>(
                     } else {
                         // Check allocation alignment and offset alignment.
                         if alloc_align.bytes() < align.bytes() {
-                            self.alignment_check_failed(alloc_align, align, check)?;
+                            M::alignment_check_failed(self, alloc_align, align, check)?;
                         }
                         self.check_offset_align(offset.bytes(), align, check)?;
                     }
@@ -472,43 +469,9 @@ fn check_offset_align(
         } else {
             // The biggest power of two through which `offset` is divisible.
             let offset_pow2 = 1 << offset.trailing_zeros();
-            self.alignment_check_failed(Align::from_bytes(offset_pow2).unwrap(), align, check)
+            M::alignment_check_failed(self, Align::from_bytes(offset_pow2).unwrap(), align, check)
         }
     }
-
-    fn alignment_check_failed(
-        &self,
-        has: Align,
-        required: Align,
-        check: CheckAlignment,
-    ) -> InterpResult<'tcx, ()> {
-        match check {
-            CheckAlignment::Error => {
-                throw_ub!(AlignmentCheckFailed { has, required })
-            }
-            CheckAlignment::No => span_bug!(
-                self.cur_span(),
-                "`alignment_check_failed` called when no alignment check requested"
-            ),
-            CheckAlignment::FutureIncompat => self.tcx.struct_span_lint_hir(
-                INVALID_ALIGNMENT,
-                self.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID),
-                self.cur_span(),
-                UndefinedBehaviorInfo::AlignmentCheckFailed { has, required }.to_string(),
-                |db| {
-                    let mut stacktrace = self.generate_stacktrace();
-                    // Filter out `requires_caller_location` frames.
-                    stacktrace
-                        .retain(|frame| !frame.instance.def.requires_caller_location(*self.tcx));
-                    for frame in stacktrace {
-                        db.span_label(frame.span, format!("inside `{}`", frame.instance));
-                    }
-                    db
-                },
-            ),
-        }
-        Ok(())
-    }
 }
 
 /// Allocation accessors
index c8ba6310d590be1861dea20b5f04d25b99f98a4a..044b7ce65bd71cd65ed54597d246e1e4efc01cac 100644 (file)
@@ -23,7 +23,7 @@
 use rustc_middle::ty::InternalSubsts;
 use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable};
 use rustc_span::{def_id::DefId, Span};
-use rustc_target::abi::{self, HasDataLayout, Size, TargetDataLayout};
+use rustc_target::abi::{self, Align, HasDataLayout, Size, TargetDataLayout};
 use rustc_target::spec::abi::Abi as CallAbi;
 use rustc_trait_selection::traits;
 
@@ -197,6 +197,17 @@ fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> CheckAlignment {
     fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
         false // for now, we don't enforce validity
     }
+    fn alignment_check_failed(
+        ecx: &InterpCx<'mir, 'tcx, Self>,
+        _has: Align,
+        _required: Align,
+        _check: CheckAlignment,
+    ) -> InterpResult<'tcx, ()> {
+        span_bug!(
+            ecx.cur_span(),
+            "`alignment_check_failed` called when no alignment check requested"
+        )
+    }
 
     fn load_mir(
         _ecx: &InterpCx<'mir, 'tcx, Self>,
index 37675426f1916a62e71384dc9fdca7a6a6bb4eaf..c75fe2327de3eb0b52e35f0cbebfe02fc9282838 100644 (file)
@@ -11,6 +11,7 @@
 use rustc_mir_dataflow::value_analysis::{Map, State, TrackElem, ValueAnalysis, ValueOrPlace};
 use rustc_mir_dataflow::{lattice::FlatSet, Analysis, ResultsVisitor, SwitchIntEdgeEffects};
 use rustc_span::DUMMY_SP;
+use rustc_target::abi::Align;
 
 use crate::MirPass;
 
@@ -456,6 +457,14 @@ fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> CheckAlignment {
     fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
         unimplemented!()
     }
+    fn alignment_check_failed(
+        _ecx: &InterpCx<'mir, 'tcx, Self>,
+        _has: Align,
+        _required: Align,
+        _check: CheckAlignment,
+    ) -> interpret::InterpResult<'tcx, ()> {
+        unimplemented!()
+    }
 
     fn find_mir_or_eval_fn(
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
index 8f3c979f5ebab242423528d8a61d40e087e097e2..ab629e4711b10c0e2ca8e5fec502336575f2ab9a 100644 (file)
@@ -22,7 +22,7 @@
 };
 use rustc_span::def_id::{CrateNum, DefId};
 use rustc_span::Symbol;
-use rustc_target::abi::Size;
+use rustc_target::abi::{Size, Align};
 use rustc_target::spec::abi::Abi;
 use rustc_const_eval::const_eval::CheckAlignment;
 
@@ -766,6 +766,15 @@ fn use_addr_for_alignment_check(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool {
         ecx.machine.check_alignment == AlignmentCheck::Int
     }
 
+    fn alignment_check_failed(
+        _ecx: &InterpCx<'mir, 'tcx, Self>,
+        has: Align,
+        required: Align,
+        _check: CheckAlignment,
+    ) -> InterpResult<'tcx, ()> {
+        throw_ub!(AlignmentCheckFailed { has, required })
+    }
+
     #[inline(always)]
     fn enforce_validity(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool {
         ecx.machine.validate