From 54da14a861939114368970dee503fe07ba5ce98a Mon Sep 17 00:00:00 2001 From: LemonJ <1632798336@qq.com> Date: Wed, 13 Nov 2024 09:49:06 +0800 Subject: [PATCH 1/3] Save changes to Cargo.lock before merging --- rap/Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/rap/Cargo.lock b/rap/Cargo.lock index 173b046..17ed112 100644 --- a/rap/Cargo.lock +++ b/rap/Cargo.lock @@ -375,6 +375,7 @@ dependencies = [ "chrono", "colorful", "fern", + "lazy_static", "log", "regex", "rustc-demangle", From 71580a9f352e0b3f51dfdf256421dcb0ddcb5287 Mon Sep 17 00:00:00 2001 From: LemonJ <1632798336@qq.com> Date: Sat, 16 Nov 2024 14:41:32 +0800 Subject: [PATCH 2/3] fix:Contracts checking bug in senryx --- rap/rust-toolchain.toml | 2 +- rap/src/analysis/senryx.rs | 4 +- .../senryx/contracts/abstract_state.rs | 9 +- rap/src/analysis/senryx/contracts/checker.rs | 4 +- rap/src/analysis/senryx/contracts/contract.rs | 16 +- .../senryx/contracts/state_lattice.rs | 32 ++- rap/src/analysis/senryx/inter_record.rs | 13 +- rap/src/analysis/senryx/matcher.rs | 4 +- rap/src/analysis/senryx/visitor.rs | 215 ++++++++++++++---- .../slice_from_raw_parts/src/main.rs | 172 ++++++++------ 10 files changed, 322 insertions(+), 149 deletions(-) diff --git a/rap/rust-toolchain.toml b/rap/rust-toolchain.toml index 896b098..ef309bf 100644 --- a/rap/rust-toolchain.toml +++ b/rap/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] # The default version of the rustc compiler -channel = "nightly-2024-10-12" +channel = "nightly-2024-10-12-x86_64-unknown-linux-gnu" components = ["rustc-dev", "rust-src", "llvm-tools-preview"] diff --git a/rap/src/analysis/senryx.rs b/rap/src/analysis/senryx.rs index 1ec161f..e6c9470 100644 --- a/rap/src/analysis/senryx.rs +++ b/rap/src/analysis/senryx.rs @@ -58,11 +58,11 @@ impl<'tcx> SenryxCheck<'tcx> { pub fn pre_handle_type(&self, def_id: DefId) { let mut uig_checker = UnsafetyIsolationCheck::new(self.tcx); let func_type = uig_checker.get_type(def_id); - let mut body_visitor = BodyVisitor::new(self.tcx, def_id, true); + let mut body_visitor = BodyVisitor::new(self.tcx, def_id, 0); if func_type == 1 { let func_cons = uig_checker.search_constructor(def_id); for func_con in func_cons { - let mut cons_body_visitor = BodyVisitor::new(self.tcx, func_con, true); + let mut cons_body_visitor = BodyVisitor::new(self.tcx, func_con, 0); cons_body_visitor.path_forward_check(); // TODO: cache fields' states diff --git a/rap/src/analysis/senryx/contracts/abstract_state.rs b/rap/src/analysis/senryx/contracts/abstract_state.rs index 60476ac..7eeaa2a 100644 --- a/rap/src/analysis/senryx/contracts/abstract_state.rs +++ b/rap/src/analysis/senryx/contracts/abstract_state.rs @@ -45,8 +45,9 @@ pub enum AllocatedState { #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] pub enum AlignState { Aligned, - Small2BigCast, - Big2SmallCast, + Small2BigCast(usize, usize), + Big2SmallCast(usize, usize), + Unaligned, } #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] @@ -109,7 +110,7 @@ impl AbstractStateItem { #[derive(PartialEq)] pub struct AbstractState { - pub state_map: HashMap, + pub state_map: HashMap>, } impl AbstractState { @@ -119,7 +120,7 @@ impl AbstractState { } } - pub fn insert_abstate(&mut self, place: usize, place_state_item: AbstractStateItem) { + pub fn insert_abstate(&mut self, place: usize, place_state_item: Option) { self.state_map.insert(place, place_state_item); } } diff --git a/rap/src/analysis/senryx/contracts/checker.rs b/rap/src/analysis/senryx/contracts/checker.rs index bd6464c..e26ae21 100644 --- a/rap/src/analysis/senryx/contracts/checker.rs +++ b/rap/src/analysis/senryx/contracts/checker.rs @@ -30,8 +30,8 @@ impl SliceFromRawPartsChecker { state: StateType::AllocatedState(AllocatedState::Alloc), }, Contract::StateCheck { - op: Op::NE, - state: StateType::AlignState(AlignState::Small2BigCast), + op: Op::GT, + state: StateType::AlignState(AlignState::Unaligned), }, ], ); diff --git a/rap/src/analysis/senryx/contracts/contract.rs b/rap/src/analysis/senryx/contracts/contract.rs index 3fee5e2..04905e1 100644 --- a/rap/src/analysis/senryx/contracts/contract.rs +++ b/rap/src/analysis/senryx/contracts/contract.rs @@ -14,7 +14,9 @@ pub fn check_contract(contract: Contract, abstate_item: &AbstractStateItem) -> b } Contract::StateCheck { op, state } => { for ab_state in &abstate_item.state { - if handle_state_op(*ab_state, op, state) { + if check_is_same_state_type(ab_state, &state) + && handle_state_op(*ab_state, op, state) + { return true; } } @@ -23,6 +25,18 @@ pub fn check_contract(contract: Contract, abstate_item: &AbstractStateItem) -> b } } +pub fn check_is_same_state_type(left: &StateType, right: &StateType) -> bool { + match (*left, *right) { + (StateType::AllocatedState(_), StateType::AllocatedState(_)) => { + return true; + } + (StateType::AlignState(_), StateType::AlignState(_)) => { + return true; + } + _ => false, + } +} + pub fn handle_value_op( left: &(T, T), op: Op, diff --git a/rap/src/analysis/senryx/contracts/state_lattice.rs b/rap/src/analysis/senryx/contracts/state_lattice.rs index d9524de..b407caa 100644 --- a/rap/src/analysis/senryx/contracts/state_lattice.rs +++ b/rap/src/analysis/senryx/contracts/state_lattice.rs @@ -131,27 +131,35 @@ impl Lattice for AlignState { fn join(&self, other: Self) -> Self { match (self, other) { (AlignState::Aligned, _) => AlignState::Aligned, - (AlignState::Big2SmallCast, AlignState::Big2SmallCast) => AlignState::Big2SmallCast, - (AlignState::Big2SmallCast, AlignState::Small2BigCast) => AlignState::Big2SmallCast, - (AlignState::Big2SmallCast, AlignState::Aligned) => AlignState::Aligned, - (AlignState::Small2BigCast, _) => other, + (AlignState::Big2SmallCast(_, _), AlignState::Big2SmallCast(_, _)) => { + AlignState::Aligned + } + (AlignState::Big2SmallCast(_, _), AlignState::Small2BigCast(_, _)) => { + AlignState::Unaligned + } + (AlignState::Big2SmallCast(_, _), AlignState::Aligned) => AlignState::Aligned, + (AlignState::Unaligned, _) => AlignState::Unaligned, + (_, AlignState::Unaligned) => AlignState::Unaligned, + _ => other, } } fn meet(&self, other: Self) -> Self { - match (self, other) { - (AlignState::Aligned, _) => other, - (AlignState::Big2SmallCast, AlignState::Big2SmallCast) => AlignState::Big2SmallCast, - (AlignState::Big2SmallCast, AlignState::Small2BigCast) => AlignState::Small2BigCast, - (AlignState::Big2SmallCast, AlignState::Aligned) => AlignState::Big2SmallCast, - (AlignState::Small2BigCast, _) => AlignState::Small2BigCast, - } + other + // match (self, other) { + // (AlignState::Aligned, _) => other, + // (AlignState::Big2SmallCast(_,_), AlignState::Big2SmallCast(_,_)) => AlignState::Aligned, + // (AlignState::Big2SmallCast(_,_), AlignState::Small2BigCast(_,_)) => AlignState::Unaligned, + // (AlignState::Big2SmallCast(_,_), AlignState::Aligned) => AlignState::Big2SmallCast(_,_), + // (AlignState::Small2BigCast, _) => AlignState::Small2BigCast, + // } } fn less_than(&self, other: Self) -> bool { match (self, other) { (_, AlignState::Aligned) => true, - (AlignState::Small2BigCast, AlignState::Big2SmallCast) => true, + (AlignState::Small2BigCast(_, _), AlignState::Big2SmallCast(_, _)) => true, + (AlignState::Small2BigCast(_, _), AlignState::Unaligned) => true, _ => false, } } diff --git a/rap/src/analysis/senryx/inter_record.rs b/rap/src/analysis/senryx/inter_record.rs index 90086c9..0d9c694 100644 --- a/rap/src/analysis/senryx/inter_record.rs +++ b/rap/src/analysis/senryx/inter_record.rs @@ -11,14 +11,14 @@ lazy_static! { // static mut GLOBAL_INTER_RECORDER: HashMap = HashMap::new(); pub struct InterAnalysisRecord { - pub pre_analysis_state: HashMap, - pub post_analysis_state: HashMap, + pub pre_analysis_state: HashMap>, + pub post_analysis_state: HashMap>, } impl InterAnalysisRecord { pub fn new( - pre_analysis_state: HashMap, - post_analysis_state: HashMap, + pre_analysis_state: HashMap>, + post_analysis_state: HashMap>, ) -> Self { Self { pre_analysis_state, @@ -26,7 +26,10 @@ impl InterAnalysisRecord { } } - pub fn is_pre_state_same(&self, other_pre_state: &HashMap) -> bool { + pub fn is_pre_state_same( + &self, + other_pre_state: &HashMap>, + ) -> bool { self.pre_analysis_state == *other_pre_state } } diff --git a/rap/src/analysis/senryx/matcher.rs b/rap/src/analysis/senryx/matcher.rs index b99d528..991dfdf 100644 --- a/rap/src/analysis/senryx/matcher.rs +++ b/rap/src/analysis/senryx/matcher.rs @@ -32,10 +32,10 @@ fn process_checker(checker: &dyn Checker, args: &Box<[Spanned]>, abstat for contract in contracts_vec { let arg_place = get_arg_place(&args[*idx].node); if arg_place == 0 { - return; + continue; } if let Some(abstate_item) = abstate.state_map.get(&arg_place) { - if !check_contract(*contract, abstate_item) { + if !check_contract(*contract, &abstate_item.clone().unwrap()) { println!("Contract failed! ---- {:?}", contract); } else { println!("Contract passed! ---- {:?}", contract); diff --git a/rap/src/analysis/senryx/visitor.rs b/rap/src/analysis/senryx/visitor.rs index 6a66887..64c8bf9 100644 --- a/rap/src/analysis/senryx/visitor.rs +++ b/rap/src/analysis/senryx/visitor.rs @@ -1,18 +1,20 @@ use crate::analysis::safedrop::graph::SafeDropGraph; +// use crate::analysis::utils::show_mir::display_mir; use crate::rap_warn; +use rustc_span::source_map::Spanned; use std::collections::{HashMap, HashSet}; use super::contracts::abstract_state::{ AbstractState, AbstractStateItem, AlignState, StateType, VType, Value, }; use super::inter_record::{InterAnalysisRecord, GLOBAL_INTER_RECORDER}; -use super::matcher::match_unsafe_api_and_check_contracts; +use super::matcher::{get_arg_place, match_unsafe_api_and_check_contracts}; use rustc_hir::def_id::DefId; use rustc_middle::ty::TyCtxt; use rustc_middle::{ mir::{ - self, AggregateKind, BasicBlock, BasicBlockData, Local, Operand, Place, Rvalue, Statement, - StatementKind, Terminator, TerminatorKind, + self, AggregateKind, BasicBlock, BasicBlockData, CastKind, Local, Operand, Place, Rvalue, + Statement, StatementKind, Terminator, TerminatorKind, }, ty::{self, GenericArgKind, Ty, TyKind}, }; @@ -24,11 +26,11 @@ pub struct BodyVisitor<'tcx> { // abstract_states records the path index and variables' ab states in this path pub abstract_states: HashMap, pub unsafe_callee_report: HashMap, - pub first_layer_flag: bool, + pub visit_time: usize, } impl<'tcx> BodyVisitor<'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, def_id: DefId, first_layer_flag: bool) -> Self { + pub fn new(tcx: TyCtxt<'tcx>, def_id: DefId, visit_time: usize) -> Self { let body = tcx.optimized_mir(def_id); Self { tcx, @@ -36,13 +38,14 @@ impl<'tcx> BodyVisitor<'tcx> { safedrop_graph: SafeDropGraph::new(body, tcx, def_id), abstract_states: HashMap::new(), unsafe_callee_report: HashMap::new(), - first_layer_flag, + visit_time, } } pub fn path_forward_check(&mut self) { let paths = self.get_all_paths(); let body = self.tcx.optimized_mir(self.def_id); + // display_mir(self.def_id,&body); for (index, path_info) in paths.iter().enumerate() { self.abstract_states.insert(index, AbstractState::new()); for block_index in path_info.iter() { @@ -69,7 +72,13 @@ impl<'tcx> BodyVisitor<'tcx> { } } } - self.abstract_states_mop(); + // self.abstract_states_mop(); + if self.visit_time == 0 { + // display_mir(self.def_id,body); + println!("---------------"); + println!("--def_id: {:?} \n--paths: {:?}", self.def_id, paths); + self.abstate_debug(); + } } pub fn path_analyze_block( @@ -78,7 +87,7 @@ impl<'tcx> BodyVisitor<'tcx> { path_index: usize, bb_index: usize, ) { - for statement in block.statements.iter().rev() { + for statement in block.statements.iter() { self.path_analyze_statement(statement, path_index); } self.path_analyze_terminator(&block.terminator(), path_index, bb_index); @@ -102,7 +111,7 @@ impl<'tcx> BodyVisitor<'tcx> { if let Operand::Constant(func_constant) = func { if let ty::FnDef(ref callee_def_id, raw_list) = func_constant.const_.ty().kind() { - if self.first_layer_flag { + if self.visit_time == 0 { for generic_arg in raw_list.iter() { match generic_arg.unpack() { GenericArgKind::Type(ty) => { @@ -117,8 +126,7 @@ impl<'tcx> BodyVisitor<'tcx> { } } } - //TODO:path_inter_analyze - self.handle_call(callee_def_id); + self.handle_call(callee_def_id, args, path_index); } } } @@ -164,9 +172,16 @@ impl<'tcx> BodyVisitor<'tcx> { match rvalue { Rvalue::Use(op) => match op { Operand::Move(rplace) | Operand::Copy(rplace) => { - let _rpjc_local = - self.safedrop_graph - .projection(self.tcx, true, rplace.clone()); + let rpjc_local = self + .safedrop_graph + .projection(self.tcx, true, rplace.clone()); + if let Some(ab_state) = self.abstract_states.get(&path_index) { + // println!("------{:?}, {:?}-----",path_index,rpjc_local); + if let Some(r_state_item) = ab_state.state_map.get(&rpjc_local) { + // println!("------{:?}-----",r_state_item.clone().unwrap()); + self.insert_path_abstate(path_index, lpjc_local, r_state_item.clone()); + } + } } _ => {} }, @@ -188,30 +203,14 @@ impl<'tcx> BodyVisitor<'tcx> { VType::Pointer(align, size), HashSet::from([StateType::AlignState(AlignState::Aligned)]), ); - self.insert_path_abstate(path_index, lpjc_local, abitem); + self.insert_path_abstate(path_index, lpjc_local, Some(abitem)); } - Rvalue::Cast(_cast_kind, op, ty) => match op { + Rvalue::Cast(cast_kind, op, ty) => match op { Operand::Move(rplace) | Operand::Copy(rplace) => { let rpjc_local = self .safedrop_graph .projection(self.tcx, true, rplace.clone()); - let (src_align, _src_size) = self.get_layout_by_place_usize(rpjc_local); - let (dst_align, dst_size) = self.visit_ty_and_get_layout(*ty); - let state = match dst_align.cmp(&src_align) { - std::cmp::Ordering::Greater => { - StateType::AlignState(AlignState::Small2BigCast) - } - std::cmp::Ordering::Less => { - StateType::AlignState(AlignState::Big2SmallCast) - } - std::cmp::Ordering::Equal => StateType::AlignState(AlignState::Aligned), - }; - let abitem = AbstractStateItem::new( - (Value::None, Value::None), - VType::Pointer(dst_align, dst_size), - HashSet::from([state]), - ); - self.insert_path_abstate(path_index, lpjc_local, abitem); + self.handle_cast(rpjc_local, lpjc_local, ty, path_index, cast_kind); } _ => {} }, @@ -235,25 +234,79 @@ impl<'tcx> BodyVisitor<'tcx> { } } - pub fn handle_call(&mut self, def_id: &DefId) { - let pre_analysis_state = HashMap::new(); + pub fn handle_call( + &mut self, + def_id: &DefId, + args: &Box<[Spanned]>, + path_index: usize, + ) { + if !self.tcx.is_mir_available(def_id) { + return; + } + + // get pre analysis state + let mut pre_analysis_state = HashMap::new(); + for (idx, arg) in args.iter().enumerate() { + let arg_place = get_arg_place(&arg.node); + let ab_state_item = self.get_abstate_by_place_in_path(arg_place, path_index); + pre_analysis_state.insert(idx, ab_state_item); + } + + // check cache let mut recorder = GLOBAL_INTER_RECORDER.lock().unwrap(); if let Some(record) = recorder.get_mut(def_id) { if record.is_pre_state_same(&pre_analysis_state) { // update directly - self.update_inter_state_directly(); + self.update_post_state(&record.post_analysis_state, args, path_index); return; } } - let _inter_body_visitor = BodyVisitor::new(self.tcx, *def_id, false).path_forward_check(); - let post_analysis_state = HashMap::new(); + drop(recorder); + + // update post states and cache + let mut inter_body_visitor: BodyVisitor<'_> = + BodyVisitor::new(self.tcx, *def_id, self.visit_time + 1); + inter_body_visitor.path_forward_check(); + let post_analysis_state: HashMap> = + inter_body_visitor.get_args_post_states(); + // self.update_post_state(&post_analysis_state, args, path_index); + let mut recorder = GLOBAL_INTER_RECORDER.lock().unwrap(); recorder.insert( *def_id, InterAnalysisRecord::new(pre_analysis_state, post_analysis_state), ); + // drop(recorder); + } + + // if inter analysis's params are in mut_ref, then we should update their post states + pub fn update_post_state( + &mut self, + post_state: &HashMap>, + args: &Box<[Spanned]>, + path_index: usize, + ) { + for (idx, arg) in args.iter().enumerate() { + let arg_place = get_arg_place(&arg.node); + if let Some(state_item) = post_state.get(&idx) { + self.insert_path_abstate(path_index, arg_place, state_item.clone()); + } + } } - pub fn update_inter_state_directly(&mut self) {} + pub fn get_args_post_states(&mut self) -> HashMap> { + let final_states = self.abstract_states_mop(); + let mut result_states = HashMap::new(); + let fn_sig = self.tcx.fn_sig(self.def_id).skip_binder(); + let num_params = fn_sig.inputs().skip_binder().len(); + for i in 0..num_params { + if let Some(state) = final_states.state_map.get(&(i + 1)) { + result_states.insert(i, state.clone()); + } else { + result_states.insert(i, None); + } + } + result_states + } pub fn visit_ty_and_get_layout(&self, ty: Ty<'tcx>) -> (usize, usize) { match ty.kind() { @@ -270,7 +323,7 @@ impl<'tcx> BodyVisitor<'tcx> { results } - pub fn abstract_states_mop(&mut self) { + pub fn abstract_states_mop(&mut self) -> AbstractState { let mut result_state = AbstractState { state_map: HashMap::new(), }; @@ -278,7 +331,10 @@ impl<'tcx> BodyVisitor<'tcx> { for (_path_idx, abstract_state) in &self.abstract_states { for (var_index, state_item) in &abstract_state.state_map { if let Some(existing_state_item) = result_state.state_map.get_mut(&var_index) { - existing_state_item.meet_state_item(state_item); + existing_state_item + .clone() + .unwrap() + .meet_state_item(&state_item.clone().unwrap()); } else { result_state .state_map @@ -286,6 +342,7 @@ impl<'tcx> BodyVisitor<'tcx> { } } } + result_state } pub fn abstate_debug(&self) { @@ -351,8 +408,11 @@ impl<'tcx> BodyVisitor<'tcx> { &mut self, path_index: usize, place: usize, - abitem: AbstractStateItem, + abitem: Option, ) { + if self.visit_time == 0 { + println!("insert state of place: {}", place); + } self.abstract_states .entry(path_index) .or_insert_with(|| AbstractState { @@ -371,11 +431,72 @@ impl<'tcx> BodyVisitor<'tcx> { pub fn get_layout_by_ty(&self, ty: Ty<'tcx>) -> (usize, usize) { let param_env = self.tcx.param_env(self.def_id); - let layout = self.tcx.layout_of(param_env.and(ty)).unwrap(); - let align = layout.align.abi.bytes_usize(); - let size = layout.size.bytes() as usize; - (align, size) + if let Ok(_) = self.tcx.layout_of(param_env.and(ty)) { + let layout = self.tcx.layout_of(param_env.and(ty)).unwrap(); + let align = layout.align.abi.bytes_usize(); + let size = layout.size.bytes() as usize; + return (align, size); + } + return (0, 0); + } + + pub fn get_abstate_by_place_in_path( + &self, + place: usize, + path_index: usize, + ) -> Option { + if let Some(abstate) = self.abstract_states.get(&path_index) { + if let Some(_) = abstate.state_map.get(&place).cloned() { + return abstate.state_map.get(&place).cloned().unwrap(); + } + } + return None; + } + + pub fn handle_cast( + &mut self, + rpjc_local: usize, + lpjc_local: usize, + ty: &Ty<'tcx>, + path_index: usize, + cast_kind: &CastKind, + ) { + let mut src_align = self.get_layout_by_place_usize(rpjc_local).0; + match cast_kind { + CastKind::PtrToPtr => { + if let Some(r_abitem) = self.get_abstate_by_place_in_path(rpjc_local, path_index) { + for state in &r_abitem.state { + if let StateType::AlignState(r_align_state) = state { + match r_align_state { + AlignState::Small2BigCast(from, _to) + | AlignState::Big2SmallCast(from, _to) => { + src_align = *from; + } + _ => {} + } + } + } + } + let (dst_align, dst_size) = self.visit_ty_and_get_layout(*ty); + let align_state = match dst_align.cmp(&src_align) { + std::cmp::Ordering::Greater => { + StateType::AlignState(AlignState::Small2BigCast(src_align, dst_align)) + } + std::cmp::Ordering::Less => { + StateType::AlignState(AlignState::Big2SmallCast(src_align, dst_align)) + } + std::cmp::Ordering::Equal => StateType::AlignState(AlignState::Aligned), + }; + let abitem = AbstractStateItem::new( + (Value::None, Value::None), + VType::Pointer(dst_align, dst_size), + HashSet::from([align_state]), + ); + self.insert_path_abstate(path_index, lpjc_local, Some(abitem)); + } + _ => {} + } } - pub fn get_abstate_by_place(&self) {} + pub fn handle_binary_op(&mut self) {} } diff --git a/tests/senryx_tests/slice_from_raw_parts/src/main.rs b/tests/senryx_tests/slice_from_raw_parts/src/main.rs index eedd859..5c66264 100644 --- a/tests/senryx_tests/slice_from_raw_parts/src/main.rs +++ b/tests/senryx_tests/slice_from_raw_parts/src/main.rs @@ -1,90 +1,116 @@ -use std::ptr; +// use std::ptr; use std::slice; -use std::mem::MaybeUninit; +// use std::mem::MaybeUninit; -struct MySliceWrapperTest { - data: *const T, - len: usize, -} +// struct MySliceWrapperTest { +// data: *const T, +// len: usize, +// } -impl MySliceWrapperTest { - fn new() -> Self { - let uninit_data = MaybeUninit::<[T; 10]>::uninit(); - let data = uninit_data.as_ptr() as *const T; - MySliceWrapperTest { data, len: 10 } - } +// impl MySliceWrapperTest { +// fn new() -> Self { +// let uninit_data = MaybeUninit::<[T; 10]>::uninit(); +// let data = uninit_data.as_ptr() as *const T; +// MySliceWrapperTest { data, len: 10 } +// } - fn get_slice(&self, offset: usize, length: usize) -> &[T] { - assert!(offset + length <= self.len, "Requested slice is out of bounds"); - let adjusted_data = unsafe { self.data.add(offset) }; - // Fail(Allocated): 'adjusted_data' points to uninit memory - // Fail(Aligned): 'adjusted_data' may be not aligned due to the offset - unsafe { slice::from_raw_parts(adjusted_data, length) } - } -} +// fn get_slice(&self, offset: usize, length: usize) -> &[T] { +// assert!(offset + length <= self.len, "Requested slice is out of bounds"); +// let adjusted_data = unsafe { self.data.add(offset) }; +// // Fail(Allocated): 'adjusted_data' points to uninit memory +// // Fail(Aligned): 'adjusted_data' may be not aligned due to the offset +// unsafe { slice::from_raw_parts(adjusted_data, length) } +// } +// } -fn test1() { - let len: usize = 0; - let data = ptr::null::(); - // Fail(Allocated): 'data' is null, which violates the requirement that it must be non-null - let slice: &[i32] = unsafe { slice::from_raw_parts(data, len) }; -} +// fn test1() { +// let len: usize = 0; +// let data = ptr::null::(); +// // Fail(Allocated): 'data' is null, which violates the requirement that it must be non-null +// let slice: &[i32] = unsafe { slice::from_raw_parts(data, len) }; +// } -fn test2() { - let len: usize = 3; - let uninit_data = MaybeUninit::<[i32; 3]>::uninit(); - let data = uninit_data.as_ptr() as *const i32; - // Fail(Initialized): 'data' points to uninitialized memory, which violates the initialization requirement - let slice: &[i32] = unsafe { slice::from_raw_parts(data, len) }; - println!("First element: {}", slice[0]); -} +// fn test2() { +// let len: usize = 3; +// let uninit_data = MaybeUninit::<[i32; 3]>::uninit(); +// let data = uninit_data.as_ptr() as *const i32; +// // Fail(Initialized): 'data' points to uninitialized memory, which violates the initialization requirement +// let slice: &[i32] = unsafe { slice::from_raw_parts(data, len) }; +// println!("First element: {}", slice[0]); +// } -fn test3() { - let part1 = Box::new(1); - let part2 = Box::new(2); - let data = [Box::into_raw(part1), Box::into_raw(part2)].as_ptr() as *const i32; - let len = 2; - // Fail(Dereferencable): 'data' points across multiple allocated objects, violating the single allocation constraint - let slice: &[i32] = unsafe { slice::from_raw_parts(data, len) }; - println!("Slice elements: {:?}", slice); -} +// fn test3() { +// let part1 = Box::new(1); +// let part2 = Box::new(2); +// let data = [Box::into_raw(part1), Box::into_raw(part2)].as_ptr() as *const i32; +// let len = 2; +// // Fail(Dereferencable): 'data' points across multiple allocated objects, violating the single allocation constraint +// let slice: &[i32] = unsafe { slice::from_raw_parts(data, len) }; +// println!("Slice elements: {:?}", slice); +// } -fn test4() { - let unaligned = [0u8; 5]; - let data = unaligned.as_ptr().wrapping_offset(1) as *const i32; +// fn test4() { +// let unaligned = [0u8; 5]; +// let data = unaligned.as_ptr().wrapping_offset(1) as *const i32; +// let len = 1; +// // Fail(Layout): 'data' is not aligned, violating the alignment requirement +// let slice: &[i32] = unsafe { slice::from_raw_parts(data, len) }; +// println!("Slice elements: {:?}", slice); +// } + +// fn test5(offset:usize) { +// let unaligned = [0u32; 5]; +// let ptr = unaligned.as_ptr() as *const u8; +// let data = unsafe { ptr.add(offset) as *const i32 }; +// let len = 1; +// // Fail(Layout): 'data' is not aligned, violating the alignment requirement +// let slice: &[i32] = unsafe { slice::from_raw_parts(data, len) }; +// println!("Slice elements: {:?}", slice); +// } + + +/// offset: _1 +/// unaligned: _2 +/// unaligned.as_ptr(): _4 +/// ptr: _3 +/// data: _7 _12 +fn test5(offset:usize) { + let unaligned = [0u32; 5]; + let ptr = unaligned.as_ptr() as *const u8; + let data = ptr as *mut i32; let len = 1; // Fail(Layout): 'data' is not aligned, violating the alignment requirement - let slice: &[i32] = unsafe { slice::from_raw_parts(data, len) }; - println!("Slice elements: {:?}", slice); + let slice: &[i32] = unsafe { slice::from_raw_parts_mut(data, len) }; + // println!("Slice elements: {:?}", slice); } -fn test5() { - let data: *const u8 = Box::leak(Box::new(0)); - let len: usize = (isize::MAX as usize) / std::mem::size_of::() + 1; - // Pass(Allocated \ Aligned): data is allocated and aligned - // Fail(Bounded): 'len' is out of the max value - // Fail(Dereferencable \ Initialized): 'data' onnly points to the memory with a 'u8' size, but the 'len' is out of this range - let slice: &[u8] = unsafe { slice::from_raw_parts(data, len) }; - if let Some(last_element) = slice.last() { - println!("Last element: {}", last_element); - } else { - println!("Slice is empty"); - } -} +// fn test5() { +// let data: *const u8 = Box::leak(Box::new(0)); +// let len: usize = (isize::MAX as usize) / std::mem::size_of::() + 1; +// // Pass(Allocated \ Aligned): data is allocated and aligned +// // Fail(Bounded): 'len' is out of the max value +// // Fail(Dereferencable \ Initialized): 'data' onnly points to the memory with a 'u8' size, but the 'len' is out of this range +// let slice: &[u8] = unsafe { slice::from_raw_parts(data, len) }; +// if let Some(last_element) = slice.last() { +// println!("Last element: {}", last_element); +// } else { +// println!("Slice is empty"); +// } +// } -fn test6(a: &mut [u8], b: &[u32; 20]) { - unsafe { - let c = slice::from_raw_parts_mut(a.as_mut_ptr() as *mut u32, 20); - for i in 0..20 { - c[i] ^= b[i]; - } - } -} +// fn test6(a: &mut [u8], b: &[u32; 20]) { +// unsafe { +// let c = slice::from_raw_parts_mut(a.as_mut_ptr() as *mut u32, 20); +// for i in 0..20 { +// c[i] ^= b[i]; +// } +// } +// } fn main() { - test1(); - let mut x = [0u8;40]; - let y = [0u32;20]; - // test2(&mut x[1..32], &y); + test5(3); + // let mut x = [0u8;40]; + // let y = [0u32;20]; + // test6(&mut x[1..32], &y); } From 233cb21cbb7b20c5737222f220029a4b8700de67 Mon Sep 17 00:00:00 2001 From: LemonJ <1632798336@qq.com> Date: Sat, 16 Nov 2024 14:47:11 +0800 Subject: [PATCH 3/3] withdraw changes in toolchain --- rap/rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rap/rust-toolchain.toml b/rap/rust-toolchain.toml index ef309bf..896b098 100644 --- a/rap/rust-toolchain.toml +++ b/rap/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] # The default version of the rustc compiler -channel = "nightly-2024-10-12-x86_64-unknown-linux-gnu" +channel = "nightly-2024-10-12" components = ["rustc-dev", "rust-src", "llvm-tools-preview"]