From 5f496286c1d6a679d4174f55e243f2c6bf98f5fc Mon Sep 17 00:00:00 2001 From: David Anekstein Date: Sun, 15 Oct 2023 18:01:07 -0400 Subject: [PATCH] fix bug in rebase --- c2rust-analyze/src/context.rs | 36 +++++++++++++++-------- c2rust-analyze/src/dataflow/type_check.rs | 4 +-- c2rust-analyze/src/rewrite/expr/mir_op.rs | 2 +- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/c2rust-analyze/src/context.rs b/c2rust-analyze/src/context.rs index d2f5c4fccd..c23fde341e 100644 --- a/c2rust-analyze/src/context.rs +++ b/c2rust-analyze/src/context.rs @@ -945,7 +945,16 @@ impl<'a, 'tcx> AnalysisCtxt<'a, 'tcx> { } } - /// Returns the [`LTy`] of an [`Rvalue`] and a boolean indicating whether or + /// Returns the [`LTy`] of an [`Rvalue`] + pub fn type_of_rvalue(&self, rv: &Rvalue<'tcx>, loc: Location) -> LTy<'tcx> { + if let Some(lty) = self.rvalue_tys.get(&loc) { + return lty; + } + + self.derived_type_of_rvalue(rv) + } + + /// Returns a boolean indicating whether or /// not the `Rvalue` is a reference or pointer containing a field projection. /// For example, the following [`Rvalue`]s will satisfy that criteria: /// - let r1 = std::ptr::addr_of!(x.field); @@ -954,13 +963,19 @@ impl<'a, 'tcx> AnalysisCtxt<'a, 'tcx> { /// The following will NOT satisfy that critera: /// - let r1 = x.field; /// - let r2 = x.field + y; - pub fn type_of_rvalue(&self, rv: &Rvalue<'tcx>, loc: Location) -> (LTy<'tcx>, bool) { - let mut has_field_projection = false; - if let Some(lty) = self.rvalue_tys.get(&loc) { - return (lty, false); + pub fn has_field_projection(&self, rv: &Rvalue<'tcx>) -> bool { + if let Some(desc) = describe_rvalue(rv) { + match desc { + RvalueDesc::Project { proj, .. } | RvalueDesc::AddrOfLocal { proj, .. } => { + for p in proj { + if let PlaceElem::Field(..) = p { + return true; + } + } + } + } } - - self.derived_type_of_rvalue(rv) + false } /// In some cases, we can compute an `LTy` for an `Rvalue` that uses `PointerId`s derived from @@ -1003,9 +1018,6 @@ impl<'a, 'tcx> AnalysisCtxt<'a, 'tcx> { let mut pointee_lty = pointee_lty; for p in proj { - if let PlaceElem::Field(..) = p { - has_field_projection = true; - } pointee_lty = self.projection_lty(pointee_lty, p); } @@ -1024,7 +1036,7 @@ impl<'a, 'tcx> AnalysisCtxt<'a, 'tcx> { ); let args = self.lcx().mk_slice(&[pointee_lty]); - return (self.lcx().mk(ty, args, ptr), has_field_projection); + return self.lcx().mk(ty, args, ptr); } } @@ -1056,7 +1068,7 @@ impl<'a, 'tcx> AnalysisCtxt<'a, 'tcx> { Rvalue::ShallowInitBox(ref _op, _ty) => todo!("type_of ShallowInitBox: rv = {rv:?}"), }; - (ty, false) + ty } pub fn projection_lty(&self, lty: LTy<'tcx>, proj: &PlaceElem<'tcx>) -> LTy<'tcx> { diff --git a/c2rust-analyze/src/dataflow/type_check.rs b/c2rust-analyze/src/dataflow/type_check.rs index 8c59386f3a..05084b170d 100644 --- a/c2rust-analyze/src/dataflow/type_check.rs +++ b/c2rust-analyze/src/dataflow/type_check.rs @@ -383,10 +383,10 @@ impl<'tcx> TypeChecker<'tcx, '_> { self.visit_place(pl, Mutability::Mut); let pl_lty = self.acx.type_of(pl); - let (rv_lty, has_field_projection) = self.acx.type_of_rvalue(rv, loc); + let rv_lty = self.acx.type_of_rvalue(rv, loc); self.visit_rvalue(rv, rv_lty); - if has_field_projection { + if self.acx.has_field_projection(rv) { // Fields don't get offset permissions propagated to their base pointer self.do_assign_except( pl_lty, diff --git a/c2rust-analyze/src/rewrite/expr/mir_op.rs b/c2rust-analyze/src/rewrite/expr/mir_op.rs index 06c5079999..bcc3a71192 100644 --- a/c2rust-analyze/src/rewrite/expr/mir_op.rs +++ b/c2rust-analyze/src/rewrite/expr/mir_op.rs @@ -227,7 +227,7 @@ impl<'a, 'tcx> ExprRewriteVisitor<'a, 'tcx> { _ => {} }; - let (rv_lty, _) = self.acx.type_of_rvalue(rv, loc); + let rv_lty = self.acx.type_of_rvalue(rv, loc); self.enter_rvalue(|v| v.visit_rvalue(rv, Some(rv_lty))); // The cast from `rv_lty` to `pl_lty` should be applied to the RHS. self.enter_rvalue(|v| v.emit_cast_lty_lty(rv_lty, pl_lty));