Skip to content

Commit 93a64db

Browse files
committed
Reapply fixes
1 parent ff00738 commit 93a64db

File tree

23 files changed

+157
-86
lines changed

23 files changed

+157
-86
lines changed

c2rust-transpile/src/rust_ast/set_span.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ impl SetSpan for Expr {
140140
RangeLimits::Closed(mut r) => r.spans[0] = s,
141141
RangeLimits::HalfOpen(mut r) => r.spans[0] = s,
142142
},
143+
Expr::RawAddr(e) => e.and_token.span = s,
143144
Expr::Reference(e) => e.and_token.span = s,
144145
Expr::Return(e) => e.return_token.span = s,
145146
Expr::Try(e) => e.question_token.span = s,

c2rust-transpile/src/translator/mod.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4510,22 +4510,36 @@ impl<'c> Translation<'c> {
45104510
_ => {
45114511
// Variable length arrays are already represented as pointers.
45124512
if let CTypeKind::VariableArray(..) = source_ty_kind {
4513-
Ok(val)
4513+
return Ok(val);
4514+
}
4515+
4516+
let mutbl = if is_const {
4517+
Mutability::Immutable
45144518
} else {
4515-
let mutbl = if is_const {
4516-
Mutability::Immutable
4519+
Mutability::Mutable
4520+
};
4521+
4522+
let target_element_ty = self.convert_type(target_cty.ctype)?;
4523+
4524+
Ok(val.map(|mut val| {
4525+
self.use_feature("raw_ref_op");
4526+
4527+
// TODO: The currently used nightly doesn't allow `&raw mut` in
4528+
// static initialisers, but it's allowed since version 1.83.
4529+
// So we take a `&raw const` and then cast.
4530+
// Remove this exemption when the version is updated.
4531+
if ctx.is_static && matches!(mutbl, Mutability::Mutable) {
4532+
val = mk().raw_borrow_expr(val);
45174533
} else {
4518-
Mutability::Mutable
4519-
};
4520-
let target_ty = self.convert_type(target_cty.ctype)?;
4521-
4522-
Ok(val.map(|x| {
4523-
self.use_feature("raw_ref_op");
4524-
let borrow = mk().set_mutbl(mutbl).raw_borrow_expr(x);
4525-
// TODO: Change to call `ptr::as_[mut]_ptr` once that is available.
4526-
mk().cast_expr(borrow, target_ty)
4527-
}))
4528-
}
4534+
val = mk().set_mutbl(mutbl).raw_borrow_expr(val);
4535+
}
4536+
4537+
// Cast to element type.
4538+
// TODO: Change to call `ptr::as_[mut]_ptr` once that is available,
4539+
// and cast only if `source_ty_kind.element_ty() != pointee.ctype`
4540+
// (`array_ptr_get` feature added to nightly in January 2024)
4541+
mk().cast_expr(val, target_element_ty)
4542+
}))
45294543
}
45304544
}
45314545
}

c2rust-transpile/src/translator/operators.rs

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ impl<'c> Translation<'c> {
901901
lrvalue: LRValue,
902902
) -> TranslationResult<WithStmts<Box<Expr>>> {
903903
let CQualTypeId { ctype, .. } = cqual_type;
904+
let ty = self.convert_type(ctype)?;
904905
let resolved_ctype = self.ast_context.resolve_type(ctype);
905906

906907
let mut unary = match name {
@@ -923,27 +924,54 @@ impl<'c> Translation<'c> {
923924
// In this translation, there are only pointers to functions and
924925
// & becomes a no-op when applied to a function.
925926

926-
let arg = self.convert_expr(ctx.used().set_needs_address(true), arg, None)?;
927+
let val = self.convert_expr(ctx.used().set_needs_address(true), arg, None)?;
927928

928929
if self.ast_context.is_function_pointer(ctype) {
929-
Ok(arg.map(|x| mk().call_expr(mk().ident_expr("Some"), vec![x])))
930+
return Ok(val.map(|x| mk().call_expr(mk().ident_expr("Some"), vec![x])));
931+
}
932+
933+
let pointee_ty =
934+
self.ast_context
935+
.get_pointee_qual_type(ctype)
936+
.ok_or_else(|| {
937+
TranslationError::generic("Address-of should return a pointer")
938+
})?;
939+
940+
let mutbl = if pointee_ty.qualifiers.is_const {
941+
Mutability::Immutable
930942
} else {
931-
let pointee_ty =
932-
self.ast_context
933-
.get_pointee_qual_type(ctype)
934-
.ok_or_else(|| {
935-
TranslationError::generic("Address-of should return a pointer")
936-
})?;
937-
938-
let mutbl = if pointee_ty.qualifiers.is_const {
939-
Mutability::Immutable
943+
Mutability::Mutable
944+
};
945+
946+
Ok(val.map(|mut val| {
947+
if matches!(
948+
arg_kind,
949+
CExprKind::Literal(..) | CExprKind::CompoundLiteral(..)
950+
) {
951+
// Rust does not extend the lifetime of temporaries with a raw borrow,
952+
// but will do so with a regular borrow.
953+
val = mk().set_mutbl(mutbl).borrow_expr(val);
954+
955+
if ctx.decay_ref.is_yes() {
956+
val = mk().cast_expr(val, ty)
957+
}
940958
} else {
941-
Mutability::Mutable
942-
};
959+
self.use_feature("raw_ref_op");
960+
961+
// TODO: The currently used nightly doesn't allow `&raw mut` in
962+
// static initialisers, but it's allowed since version 1.83.
963+
// So we take a `&raw const` and then cast.
964+
// Remove this exemption when the version is updated.
965+
if ctx.is_static && matches!(mutbl, Mutability::Mutable) {
966+
val = mk().raw_borrow_expr(val);
967+
val = mk().cast_expr(val, ty);
968+
} else {
969+
val = mk().set_mutbl(mutbl).raw_borrow_expr(val);
970+
}
971+
}
943972

944-
self.use_feature("raw_ref_op");
945-
Ok(arg.map(|a| mk().set_mutbl(mutbl).raw_borrow_expr(a)))
946-
}
973+
val
974+
}))
947975
}
948976
c_ast::UnOp::PreIncrement => self.convert_pre_increment(ctx, cqual_type, true, arg),
949977
c_ast::UnOp::PreDecrement => self.convert_pre_increment(ctx, cqual_type, false, arg),

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ input_file: c2rust-transpile/tests/snapshots/arrays.c
1212
unused_assignments,
1313
unused_mut
1414
)]
15+
#![feature(raw_ref_op)]
1516
#[derive(Copy, Clone)]
1617
#[repr(C)]
1718
pub struct C2RustUnnamed {
@@ -79,11 +80,9 @@ pub unsafe extern "C" fn entry() {
7980
&[u8; 20],
8081
&mut [std::ffi::c_char; 20],
8182
>(b"abc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
82-
let mut past_end: *mut std::ffi::c_char = &mut *simple
83-
.as_mut_ptr()
84-
.offset(::core::mem::size_of::<[std::ffi::c_char; 9]>() as isize)
85-
as *mut std::ffi::c_char;
86-
past_end = &mut *foo.offset(8 as std::ffi::c_int as isize) as *mut std::ffi::c_char;
83+
let mut past_end: *mut std::ffi::c_char = &raw mut *(&raw mut simple as *mut std::ffi::c_char)
84+
.offset(::core::mem::size_of::<[std::ffi::c_char; 9]>() as isize);
85+
past_end = &raw mut *foo.offset(8 as std::ffi::c_int as isize);
8786
}
8887
#[no_mangle]
8988
pub unsafe extern "C" fn short_initializer() {

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,29 @@ input_file: c2rust-transpile/tests/snapshots/atomics.c
1212
unused_assignments,
1313
unused_mut
1414
)]
15-
#![feature(core_intrinsics)]
15+
#![feature(core_intrinsics, raw_ref_op)]
1616
#[no_mangle]
1717
pub unsafe extern "C" fn c11_atomics(mut x: std::ffi::c_int) -> std::ffi::c_int {
18-
*&mut x = 0 as std::ffi::c_int;
19-
::core::intrinsics::atomic_store_seqcst(&mut x, 1 as std::ffi::c_int);
20-
::core::intrinsics::atomic_load_seqcst(&mut x);
21-
::core::intrinsics::atomic_xadd_seqcst(&mut x, 2 as std::ffi::c_int);
22-
::core::intrinsics::atomic_xsub_seqcst(&mut x, 1 as std::ffi::c_int);
23-
::core::intrinsics::atomic_and_seqcst(&mut x, 0xf as std::ffi::c_int);
24-
::core::intrinsics::atomic_or_seqcst(&mut x, 0x10 as std::ffi::c_int);
25-
::core::intrinsics::atomic_nand_seqcst(&mut x, 0xff as std::ffi::c_int);
26-
::core::intrinsics::atomic_xchg_seqcst(&mut x, 42 as std::ffi::c_int);
18+
*&raw mut x = 0 as std::ffi::c_int;
19+
::core::intrinsics::atomic_store_seqcst(&raw mut x, 1 as std::ffi::c_int);
20+
::core::intrinsics::atomic_load_seqcst(&raw mut x);
21+
::core::intrinsics::atomic_xadd_seqcst(&raw mut x, 2 as std::ffi::c_int);
22+
::core::intrinsics::atomic_xsub_seqcst(&raw mut x, 1 as std::ffi::c_int);
23+
::core::intrinsics::atomic_and_seqcst(&raw mut x, 0xf as std::ffi::c_int);
24+
::core::intrinsics::atomic_or_seqcst(&raw mut x, 0x10 as std::ffi::c_int);
25+
::core::intrinsics::atomic_nand_seqcst(&raw mut x, 0xff as std::ffi::c_int);
26+
::core::intrinsics::atomic_xchg_seqcst(&raw mut x, 42 as std::ffi::c_int);
2727
let mut expected: std::ffi::c_int = 42 as std::ffi::c_int;
2828
let mut desired: std::ffi::c_int = 100 as std::ffi::c_int;
29-
let fresh0 = ::core::intrinsics::atomic_cxchg_seqcst_seqcst(&mut x, *&mut expected, desired);
30-
*&mut expected = fresh0.0;
29+
let fresh0 =
30+
::core::intrinsics::atomic_cxchg_seqcst_seqcst(&raw mut x, *&raw mut expected, desired);
31+
*&raw mut expected = fresh0.0;
3132
fresh0.1;
3233
expected = 100 as std::ffi::c_int;
3334
desired = 200 as std::ffi::c_int;
3435
let fresh1 =
35-
::core::intrinsics::atomic_cxchgweak_seqcst_seqcst(&mut x, *&mut expected, desired);
36-
*&mut expected = fresh1.0;
36+
::core::intrinsics::atomic_cxchgweak_seqcst_seqcst(&raw mut x, *&raw mut expected, desired);
37+
*&raw mut expected = fresh1.0;
3738
fresh1.1;
3839
return x;
3940
}

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ input_file: c2rust-transpile/tests/snapshots/exprs.c
1212
unused_assignments,
1313
unused_mut
1414
)]
15+
#![feature(raw_ref_op)]
1516
extern "C" {
1617
fn puts(str: *const std::ffi::c_char) -> std::ffi::c_int;
1718
}
@@ -30,7 +31,7 @@ pub unsafe extern "C" fn unary_without_side_effect() {
3031
i;
3132
!i;
3233
(i == 0) as std::ffi::c_int;
33-
&mut i;
34+
&raw mut i;
3435
i;
3536
i += 1;
3637
i -= 1;
@@ -44,10 +45,11 @@ pub unsafe extern "C" fn unary_with_side_effect() {
4445
side_effect();
4546
!side_effect();
4647
(side_effect() == 0) as std::ffi::c_int;
47-
&*(b"\0" as *const u8 as *const std::ffi::c_char).offset(::core::mem::transmute::<
48+
&raw const *(b"\0" as *const u8 as *const std::ffi::c_char).offset(::core::mem::transmute::<
4849
unsafe extern "C" fn() -> std::ffi::c_int,
4950
unsafe extern "C" fn() -> std::ffi::c_int,
50-
>(side_effect)() as isize) as *const std::ffi::c_char;
51+
>(side_effect)()
52+
as isize);
5153
*arr[side_effect() as usize];
5254
arr[side_effect() as usize] = (arr[side_effect() as usize]).offset(1);
5355
arr[side_effect() as usize] = (arr[side_effect() as usize]).offset(-1);

0 commit comments

Comments
 (0)