Skip to content

Commit 973811e

Browse files
authored
Avoid unsafe in const macro translations except where necessary (#1339)
Atop #1306, as I'd rather not regress all const translations to be `unsafe` in master now that we translate const macros by default.
2 parents 3bc4fb0 + 6bef46c commit 973811e

File tree

6 files changed

+167
-145
lines changed

6 files changed

+167
-145
lines changed

c2rust-transpile/src/translator/mod.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2158,7 +2158,7 @@ impl<'c> Translation<'c> {
21582158
ctx: ExprContext,
21592159
expansions: &[CExprId],
21602160
) -> TranslationResult<(Box<Expr>, CTypeId)> {
2161-
let (mut val, ty) = expansions
2161+
let (val, ty) = expansions
21622162
.iter()
21632163
.try_fold::<Option<(WithStmts<Box<Expr>>, CTypeId)>, _, _>(None, |canonical, &id| {
21642164
self.can_convert_const_macro_expansion(id)?;
@@ -2195,7 +2195,6 @@ impl<'c> Translation<'c> {
21952195
})?
21962196
.ok_or_else(|| format_err!("Could not find a valid type for macro"))?;
21972197

2198-
val.set_unsafe();
21992198
val.to_unsafe_pure_expr()
22002199
.map(|val| (val, ty))
22012200
.ok_or_else(|| TranslationError::generic("Macro expansion is not a pure expression"))
@@ -2701,7 +2700,15 @@ impl<'c> Translation<'c> {
27012700
let mut init = init?;
27022701

27032702
stmts.append(init.stmts_mut());
2704-
let init = init.into_value();
2703+
// A `const` context is not "already unsafe" the way code within a `fn` is
2704+
// (since we translate all `fn`s as `unsafe`). Therefore, in `const` contexts,
2705+
// expose any underlying unsafety in the initializer with an `unsafe` block.
2706+
let init = if ctx.is_const {
2707+
init.to_unsafe_pure_expr()
2708+
.expect("init should not have any statements")
2709+
} else {
2710+
init.into_value()
2711+
};
27052712

27062713
let zeroed = self.implicit_default_expr(typ.ctype, false)?;
27072714
let zeroed = if ctx.is_const {
@@ -3756,21 +3763,26 @@ impl<'c> Translation<'c> {
37563763
};
37573764

37583765
let lhs = self.convert_expr(ctx.used(), arr, None)?;
3759-
Ok(lhs.map(|lhs| {
3766+
lhs.and_then(|lhs| {
37603767
// stmts.extend(lhs.stmts_mut());
37613768
// is_unsafe = is_unsafe || lhs.is_unsafe();
37623769

37633770
// Don't dereference the offset if we're still within the variable portion
37643771
if let Some(elt_type_id) = var_elt_type_id {
37653772
let mul = self.compute_size_of_expr(elt_type_id);
3766-
pointer_offset(lhs, rhs, mul, false, true)
3773+
Ok(WithStmts::new_unsafe_val(pointer_offset(
3774+
lhs, rhs, mul, false, true,
3775+
)))
37673776
} else {
3768-
mk().index_expr(lhs, cast_int(rhs, "usize", false))
3777+
Ok(WithStmts::new_val(
3778+
mk().index_expr(lhs, cast_int(rhs, "usize", false)),
3779+
))
37693780
}
3770-
}))
3781+
})
37713782
} else {
37723783
// LHS must be ref decayed for the offset method call's self param
3773-
let lhs = self.convert_expr(ctx.used().decay_ref(), *lhs, None)?;
3784+
let mut lhs = self.convert_expr(ctx.used().decay_ref(), *lhs, None)?;
3785+
lhs.set_unsafe(); // `pointer_offset` is unsafe.
37743786
lhs.result_map(|lhs| {
37753787
// stmts.extend(lhs.stmts_mut());
37763788
// is_unsafe = is_unsafe || lhs.is_unsafe();
@@ -3838,7 +3850,7 @@ impl<'c> Translation<'c> {
38383850

38393851
// Function pointer call
38403852
_ => {
3841-
let callee = self.convert_expr(ctx.used(), func, None)?;
3853+
let mut callee = self.convert_expr(ctx.used(), func, None)?;
38423854
let make_fn_ty = |ret_ty: Box<Type>| {
38433855
let ret_ty = match *ret_ty {
38443856
Type::Tuple(TypeTuple { elems: ref v, .. }) if v.is_empty() => ReturnType::Default,
@@ -3856,6 +3868,7 @@ impl<'c> Translation<'c> {
38563868
// K&R function pointer without arguments
38573869
let ret_ty = self.convert_type(ret_ty.ctype)?;
38583870
let target_ty = make_fn_ty(ret_ty);
3871+
callee.set_unsafe();
38593872
callee.map(|fn_ptr| {
38603873
let fn_ptr = unwrap_function_pointer(fn_ptr);
38613874
transmute_expr(mk().infer_ty(), target_ty, fn_ptr)
@@ -3865,6 +3878,7 @@ impl<'c> Translation<'c> {
38653878
// We have to infer the return type from our expression type
38663879
let ret_ty = self.convert_type(call_expr_ty.ctype)?;
38673880
let target_ty = make_fn_ty(ret_ty);
3881+
callee.set_unsafe();
38683882
callee.map(|fn_ptr| {
38693883
transmute_expr(mk().infer_ty(), target_ty, fn_ptr)
38703884
})

0 commit comments

Comments
 (0)