rapx/analysis/core/range_analysis/domain/SymbolicExpr.rs
1#![allow(unused_imports)]
2#![allow(unused_variables)]
3#![allow(dead_code)]
4#![allow(unused_assignments)]
5use std::{
6 collections::HashMap,
7 default,
8 fmt::{self, *},
9};
10
11use bounds::Bound;
12use intervals::*;
13use num_traits::{Bounded, Num, Zero};
14use rustc_ast::token::TokenKind::Plus;
15use rustc_hir::def_id::DefId;
16use rustc_middle::{mir::*, ty::Ty};
17use std::ops::{Add, Mul, Sub};
18
19use crate::{
20 analysis::core::range_analysis::domain::domain::{ConstConvert, IntervalArithmetic},
21 rap_trace,
22};
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub enum UnknownReason {
25 CyclicDependency,
26 CannotParse,
27 Unsupported,
28}
29
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub enum VarorConst<'tcx> {
32 Place(Place<'tcx>),
33 Constant(Const<'tcx>),
34}
35#[derive(Debug, Clone, PartialEq, Eq)]
36pub enum SymbolicExpr<'tcx> {
37 Argument(Place<'tcx>),
38 Constant(Const<'tcx>),
39 BinaryOp {
40 op: BinOp,
41 left: Box<SymbolicExpr<'tcx>>,
42 right: Box<SymbolicExpr<'tcx>>,
43 },
44 UnaryOp {
45 op: UnOp,
46 operand: Box<SymbolicExpr<'tcx>>,
47 },
48 Cast {
49 kind: CastKind,
50 operand: Box<SymbolicExpr<'tcx>>,
51 target_ty: Ty<'tcx>,
52 },
53 Ref {
54 kind: BorrowKind,
55 place_expr: Box<SymbolicExpr<'tcx>>,
56 },
57 AddressOf {
58 mutability: RawPtrKind,
59 place_expr: Box<SymbolicExpr<'tcx>>,
60 },
61 Deref(Box<SymbolicExpr<'tcx>>),
62 Len(Box<SymbolicExpr<'tcx>>),
63 Aggregate {
64 kind: Box<AggregateKind<'tcx>>,
65 fields: Vec<SymbolicExpr<'tcx>>,
66 },
67 Repeat {
68 value: Box<SymbolicExpr<'tcx>>,
69 count: Const<'tcx>,
70 },
71 Index {
72 base: Box<SymbolicExpr<'tcx>>,
73 index: Box<SymbolicExpr<'tcx>>,
74 },
75 Ssa(Vec<SymbolicExpr<'tcx>>),
76 Essa {
77 operand: Box<SymbolicExpr<'tcx>>,
78 constraint_operand: VarorConst<'tcx>,
79 bin_op: BinOp,
80 },
81 Discriminant(Box<SymbolicExpr<'tcx>>),
82 NullaryOp(NullOp<'tcx>, Ty<'tcx>),
83 ThreadLocalRef(DefId),
84 Unknown(UnknownReason),
85}
86
87impl<'tcx> fmt::Display for SymbolicExpr<'tcx> {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 match self {
90 SymbolicExpr::Argument(i) => write!(f, "arg{:?}", i),
91 SymbolicExpr::Constant(c) => write!(f, "{}", c),
92 SymbolicExpr::BinaryOp { op, left, right } => {
93 let op_str = match op {
94 BinOp::Add => "+",
95 BinOp::Sub => "-",
96 BinOp::Mul => "*",
97 BinOp::Div => "/",
98 BinOp::Rem => "%",
99 BinOp::BitXor => "^",
100 BinOp::BitAnd => "&",
101 BinOp::BitOr => "|",
102 BinOp::Shl => "<<",
103 BinOp::Shr => ">>",
104 BinOp::Eq => "==",
105 BinOp::Lt => "<",
106 BinOp::Le => "<=",
107 BinOp::Ne => "!=",
108 BinOp::Ge => ">=",
109 BinOp::Gt => ">",
110 BinOp::Offset => "offset",
111 BinOp::AddUnchecked => "+",
112 BinOp::AddWithOverflow => "+",
113 BinOp::SubUnchecked => "-",
114 BinOp::SubWithOverflow => "-",
115 BinOp::MulUnchecked => "*",
116 BinOp::MulWithOverflow => "*",
117 BinOp::ShlUnchecked => "<<",
118 BinOp::ShrUnchecked => ">>",
119 BinOp::Cmp => "cmp", // Added Cmp
120 };
121 write!(f, "({} {} {})", left, op_str, right)
122 }
123 SymbolicExpr::UnaryOp { op, operand } => {
124 let op_str = match op {
125 UnOp::Not => "!",
126 UnOp::Neg => "-",
127 UnOp::PtrMetadata => "ptr_metadata", // Added PtrMetadata
128 };
129 write!(f, "({}{})", op_str, operand)
130 }
131 SymbolicExpr::Cast {
132 operand, target_ty, ..
133 } => write!(f, "({} as {})", operand, target_ty),
134 SymbolicExpr::Ref { kind, place_expr } => match kind {
135 BorrowKind::Shared => write!(f, "&{}", place_expr),
136 BorrowKind::Mut { .. } => write!(f, "&mut {}", place_expr),
137 BorrowKind::Fake(..) => write!(f, "&shallow {}", place_expr),
138 },
139 SymbolicExpr::AddressOf {
140 mutability,
141 place_expr,
142 } => match mutability {
143 RawPtrKind::Const => write!(f, "&raw const {}", place_expr),
144 RawPtrKind::Mut => write!(f, "&raw mut {}", place_expr),
145 RawPtrKind::FakeForPtrMetadata => {
146 write!(f, "&raw FakeForPtrMetadata {}", place_expr)
147 }
148 },
149 SymbolicExpr::Deref(expr) => write!(f, "*({})", expr),
150 SymbolicExpr::Len(expr) => write!(f, "len({})", expr),
151 SymbolicExpr::Aggregate { kind, fields } => {
152 let parts: Vec<String> = fields.iter().map(|e| e.to_string()).collect();
153 match **kind {
154 AggregateKind::Tuple => write!(f, "({})", parts.join(", ")),
155 AggregateKind::Array(_) => write!(f, "[{}]", parts.join(", ")),
156 AggregateKind::Adt(def_id, ..) => write!(f, "{:?}{{..}}", def_id),
157 _ => write!(f, "aggr({})", parts.join(", ")),
158 }
159 }
160 SymbolicExpr::Repeat { value, count } => write!(f, "[{}; {}]", value, count),
161 SymbolicExpr::Index { base, index } => write!(f, "{}[{}]", base, index),
162 SymbolicExpr::Ssa(operands) => {
163 let parts: Vec<String> = operands.iter().map(|e| e.to_string()).collect();
164 write!(f, "SSA({})", parts.join(", "))
165 }
166 SymbolicExpr::Essa {
167 operand,
168 constraint_operand,
169 bin_op,
170 } => {
171 let op_str = match bin_op {
172 BinOp::Eq => "==",
173 BinOp::Lt => "<",
174 BinOp::Le => "<=",
175 BinOp::Ne => "!=",
176 BinOp::Ge => ">=",
177 BinOp::Gt => ">",
178 _ => "??", // Non-comparison ops in constraint
179 };
180 write!(
181 f,
182 "ESSA({}, {} {} {})",
183 operand, operand, op_str, constraint_operand
184 )
185 }
186 SymbolicExpr::Discriminant(expr) => write!(f, "discriminant({})", expr),
187 SymbolicExpr::NullaryOp(op, ty) => write!(f, "{:?}({})", op, ty),
188 SymbolicExpr::ThreadLocalRef(def_id) => write!(f, "tls_{:?}", def_id),
189 SymbolicExpr::Unknown(reason) => write!(f, "{{{:?}}}", reason),
190 }
191 }
192}
193
194impl<'tcx> fmt::Display for VarorConst<'tcx> {
195 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196 match self {
197 VarorConst::Place(p) => write!(f, "{:?}", p),
198 VarorConst::Constant(c) => write!(f, "{}", c),
199 }
200 }
201}
202// pub struct SymbolicExprEvaluator<'tcx, T: IntervalArithmetic + ConstConvert + Debug> {
203// /// 环境:将 Place 映射到其当前的 Range<T> 值
204// /// 注意:这里传入的是 HashMap,因为在实际分析中,Place 的值是动态变化的。
205// /// 这个 Evaluator 只是一个静态的计算器,给定一个环境就计算一次。
206// env: &'tcx HashMap<&'tcx Place<'tcx>, Range<T>>,
207// /// 用于类型推断或常量评估的类型上下文,如果需要的话
208// // tcx: TyCtxt<'tcx>, // 如果某些 Const<'tcx> 评估需要 TyCtxt,则取消注释
209// }
210
211// impl<'tcx, T> SymbolicExprEvaluator<'tcx, T>
212// where
213// T: IntervalArithmetic + ConstConvert + Debug,
214// {
215// /// 创建一个新的 SymbolicExprEvaluator 实例
216// pub fn new(env: &'tcx HashMap<&'tcx Place<'tcx>, Range<T>>) -> Self {
217// Self {
218// env,
219// // tcx, // 如果需要,在此处传入
220// }
221// }
222
223// /// 评估给定的 SymbolicExpr,返回一个 Range<T>
224// pub fn evaluate(&self, expr: &SymbolicExpr<'tcx>) -> Range<T> {
225// match expr {
226// SymbolicExpr::Argument(place) => {
227// // 函数参数:从环境中查找其区间
228// self.env.get(place)
229// .cloned()
230// .unwrap_or_else(|| {
231// rap_trace!("Warning: Argument {:?} not found in environment. Assuming full range.", place);
232// Range::default(T::min_value()) // 默认返回一个未知或全范围区间
233// })
234// }
235// SymbolicExpr::Constant(c) => {
236// // 常量:转换为 Range<T>
237// if let Some(val) = T::from_const(c) {
238// Range::new(val.clone(), val, range::RangeType)
239// } else {
240// rap_trace!("Warning: Cannot convert constant {:?} to type T. Returning full range.", c);
241// Range::default(T::min_value()) // 无法转换时返回全范围
242// }
243// }
244// SymbolicExpr::BinaryOp { op, left, right } => {
245// // 二元操作:递归评估左右操作数,然后执行区间运算
246// let left_range = self.evaluate(left);
247// let right_range = self.evaluate(right);
248
249// match op {
250// BinOp::Add | BinOp::AddUnchecked | BinOp::AddWithOverflow => left_range.add(&right_range),
251// BinOp::Sub | BinOp::SubUnchecked | BinOp::SubWithOverflow => left_range.sub(&right_range),
252// BinOp::Mul | BinOp::MulUnchecked | BinOp::MulWithOverflow => left_range.mul(&right_range),
253// BinOp::Div => left_range.div(&right_range),
254// BinOp::Rem => left_range.rem(&right_range),
255// BinOp::BitXor => left_range.bitxor(&right_range),
256// BinOp::BitAnd => left_range.bitand(&right_range),
257// BinOp::BitOr => left_range.bitor(&right_range),
258// BinOp::Shl | BinOp::ShlUnchecked => left_range.shl(&right_range), // 注意:位移操作的右操作数通常是整数
259// BinOp::Shr | BinOp::ShrUnchecked => left_range.shr(&right_range), // 同上
260
261// // 比较操作通常返回布尔值,但在区间分析中,它们用于生成新的区间约束
262// // 这里简化处理,直接返回全范围,或者根据需要实现更复杂的行为
263// BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
264// rap_trace!("Warning: Comparison operator {:?} in symbolic expression. Returning full range as range analysis for comparisons typically involves conditional updates, not direct evaluation to a single range.", op);
265// Range::default(T::min_value()) // 比较操作通常不直接产生一个数值区间
266// },
267// // Offset 通常用于指针算术,其数值行为复杂,返回全范围
268// BinOp::Offset => {
269// rap_trace!("Warning: Offset operator in symbolic expression. Returning full range.",);
270// Range::default(T::min_value())
271// },
272// BinOp::Cmp => { // 比较,通常返回 Ordering
273// rap_trace!("Warning: Cmp operator in symbolic expression. Returning full range.",);
274// Range::default(T::min_value())
275// }
276// }
277// }
278// SymbolicExpr::UnaryOp { op, operand } => {
279// // 一元操作:递归评估操作数,然后执行区间运算
280// let operand_range = self.evaluate(operand);
281// match op {
282// UnOp::Neg => operand_range.neg(),
283// UnOp::Not => operand_range.not(), // 逻辑非或位非,取决于T的实现
284// UnOp::PtrMetadata => {
285// rap_trace!("Warning: PtrMetadata operator in symbolic expression. Returning full range.",);
286// Range::default(T::min_value())
287// }
288// }
289// }
290// SymbolicExpr::Cast { kind, operand, target_ty } => {
291// // 类型转换:评估操作数,然后尝试转换区间
292// let operand_range = self.evaluate(operand);
293// // 简单的类型转换:保留原区间,但标记为不精确。
294// // 复杂的数值截断、符号扩展等需要更复杂的逻辑,可能需要 TyCtxt。
295// // 这里我们假设 T 的 IntervalArithmetic 能够处理不同大小整数的 Min/Max。
296// rap_trace!("Warning: Cast operator {:?} to {:?} in symbolic expression. Returning original range as is for simplicity, assuming T handles potential overflows/underflows implicitly via its min/max.", kind, target_ty);
297// // 实际的类型转换需要更多关于类型的信息,这里只是一个保守的估计
298// // 更精确的实现会根据 target_ty 的位宽和有无符号性来调整区间边界
299// operand_range
300// }
301// SymbolicExpr::Deref(expr) => {
302// // 解引用:通常表示访问内存位置。其值范围取决于该内存位置的内容。
303// // 在没有具体内存模型的情况下,无法计算。
304// rap_trace!("Warning: Deref operator in symbolic expression. Returning full range.",);
305// Range::default(T::min_value())
306// }
307// SymbolicExpr::Len(expr) => {
308// // 长度:通常是一个非负整数。但具体长度未知。
309// rap_trace!("Warning: Len operator in symbolic expression. Returning positive integer range.",);
310// Range::new(T::zero(), T::max_value(), range::RangeType) // 至少为0
311// }
312// SymbolicExpr::Index { base, index } => {
313// // 索引访问:访问数组/切片元素。
314// // 其值范围取决于数组/切片中所有元素的可能范围,以及索引的范围。
315// rap_trace!("Warning: Index operator in symbolic expression. Returning full range.",);
316// Range::default(T::min_value())
317// }
318// // 对于以下复杂或无法直接映射到数值区间的操作,返回全范围 (Unknown)
319// SymbolicExpr::Ref { .. } |
320// SymbolicExpr::AddressOf { .. } |
321// SymbolicExpr::Aggregate { .. } |
322// SymbolicExpr::Repeat { .. } |
323// SymbolicExpr::Discriminant { .. } |
324// SymbolicExpr::NullaryOp { .. } |
325// SymbolicExpr::ThreadLocalRef { .. } => {
326// rap_trace!("Warning: Complex/unsupported symbolic expression type {:?}. Returning full range.", expr);
327// Range::default(T::min_value())
328// }
329// SymbolicExpr::Unknown(reason) => {
330// // 表达式本身就是未知,结果也是未知
331// rap_trace!("Warning: Symbolic expression is Unknown due to reason {:?}. Propagating Unknown range.", reason);
332// Range::default(T::min_value())
333// }
334// }
335// }
336// }