Skip to content

Commit 4279da9

Browse files
committed
Use temporary variable for addr-of compound literal
1 parent 7b8f35a commit 4279da9

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

c2rust-transpile/src/translator/operators.rs

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -927,8 +927,10 @@ impl<'c> Translation<'c> {
927927
let arg = self.convert_expr(ctx.used().set_needs_address(true), arg, None)?;
928928

929929
if self.ast_context.is_function_pointer(ctype) {
930-
Ok(arg.map(|x| mk().call_expr(mk().ident_expr("Some"), vec![x])))
931-
} else {
930+
return Ok(arg.map(|x| mk().call_expr(mk().ident_expr("Some"), vec![x])));
931+
}
932+
933+
arg.and_then(|mut val| {
932934
let pointee_ty =
933935
self.ast_context
934936
.get_pointee_qual_type(ctype)
@@ -941,21 +943,33 @@ impl<'c> Translation<'c> {
941943
} else {
942944
Mutability::Mutable
943945
};
946+
let mut stmts = vec![];
947+
948+
// If we're taking the address of a compound literal, which is a temporary,
949+
// store the argument in a variable first, then take its address.
950+
if let CExprKind::CompoundLiteral(..) = arg_kind {
951+
let arg_name = self.renamer.borrow_mut().fresh();
952+
stmts.push(mk().local_stmt(Box::new(mk().local(
953+
mk().set_mutbl(mutbl).ident_pat(&arg_name),
954+
None,
955+
Some(val),
956+
))));
957+
val = mk().ident_expr(arg_name);
958+
}
944959

945-
Ok(arg.map(|a| {
946-
self.use_feature("raw_ref_op");
960+
self.use_feature("raw_ref_op");
961+
if ctx.is_static && matches!(mutbl, Mutability::Mutable) {
962+
// TODO: The currently used nightly doesn't allow `&raw mut` in static
963+
// initialisers, but the latest version does.
964+
// So we take a `&raw const` and then cast.
965+
// Remove this exemption when the version is updated.
966+
val = mk().cast_expr(mk().raw_borrow_expr(val), ty);
967+
} else {
968+
val = mk().set_mutbl(mutbl).raw_borrow_expr(val);
969+
}
947970

948-
if ctx.is_static && matches!(mutbl, Mutability::Mutable) {
949-
// TODO: The currently used nightly doesn't allow `&raw mut` in static
950-
// initialisers, but the latest version does.
951-
// So we take a `&raw const` and then cast.
952-
// Remove this exemption when the version is updated.
953-
mk().cast_expr(mk().raw_borrow_expr(a), ty)
954-
} else {
955-
mk().set_mutbl(mutbl).raw_borrow_expr(a)
956-
}
957-
}))
958-
}
971+
Ok(WithStmts::new(stmts, val))
972+
})
959973
}
960974
c_ast::UnOp::PreIncrement => self.convert_pre_increment(ctx, cqual_type, true, arg),
961975
c_ast::UnOp::PreDecrement => self.convert_pre_increment(ctx, cqual_type, false, arg),

0 commit comments

Comments
 (0)