diff --git a/c2rust-ast-builder/src/builder.rs b/c2rust-ast-builder/src/builder.rs index 71181c2876..e24cb91a0a 100644 --- a/c2rust-ast-builder/src/builder.rs +++ b/c2rust-ast-builder/src/builder.rs @@ -10,7 +10,7 @@ use syn::{__private::ToTokens, punctuated::Punctuated, *}; pub mod properties { use proc_macro2::Span; - use syn::{StaticMutability, Token}; + use syn::{PointerMutability, StaticMutability, Token}; pub trait ToToken { type Token; @@ -34,6 +34,13 @@ pub mod properties { } impl Mutability { + pub fn to_pointer_mutability(&self, span: Span) -> PointerMutability { + match self { + Mutability::Mutable => PointerMutability::Mut(Token![mut](span)), + Mutability::Immutable => PointerMutability::Const(Token![const](span)), + } + } + pub fn to_static_mutability(&self, span: Span) -> StaticMutability { match self { Mutability::Mutable => StaticMutability::Mut(Token![mut](span)), @@ -826,7 +833,7 @@ impl Builder { self.path_expr(vec![name]) } - pub fn addr_of_expr(self, e: Box) -> Box { + pub fn borrow_expr(self, e: Box) -> Box { Box::new(parenthesize_if_necessary(Expr::Reference(ExprReference { attrs: self.attrs, and_token: Token![&](self.span), @@ -835,6 +842,16 @@ impl Builder { }))) } + pub fn raw_borrow_expr(self, e: Box) -> Box { + Box::new(parenthesize_if_necessary(Expr::RawAddr(ExprRawAddr { + attrs: self.attrs, + and_token: Token![&](self.span), + raw: Token![raw](self.span), + mutability: self.mutbl.to_pointer_mutability(self.span), + expr: e, + }))) + } + pub fn mac_expr(self, mac: Macro) -> Box { Box::new(Expr::Macro(ExprMacro { attrs: self.attrs, diff --git a/c2rust-transpile/src/rust_ast/set_span.rs b/c2rust-transpile/src/rust_ast/set_span.rs index 8848e02070..2763865b0f 100644 --- a/c2rust-transpile/src/rust_ast/set_span.rs +++ b/c2rust-transpile/src/rust_ast/set_span.rs @@ -140,6 +140,7 @@ impl SetSpan for Expr { RangeLimits::Closed(mut r) => r.spans[0] = s, RangeLimits::HalfOpen(mut r) => r.spans[0] = s, }, + Expr::RawAddr(e) => e.and_token.span = s, Expr::Reference(e) => e.and_token.span = s, Expr::Return(e) => e.return_token.span = s, Expr::Try(e) => e.question_token.span = s, diff --git a/c2rust-transpile/src/translator/assembly.rs b/c2rust-transpile/src/translator/assembly.rs index a5a1577051..9f38d524bf 100644 --- a/c2rust-transpile/src/translator/assembly.rs +++ b/c2rust-transpile/src/translator/assembly.rs @@ -883,7 +883,7 @@ impl<'c> Translation<'c> { // c2rust-ast-exporter added it (there's no gcc equivalent); // in this case, we need to do what clang does and pass in // the operand by-address instead of by-value - out_expr = mk().mutbl().addr_of_expr(out_expr); + out_expr = mk().mutbl().borrow_expr(out_expr); } if let Some(_tied_operand) = tied_operands.get(&(output_idx, true)) { @@ -900,7 +900,7 @@ impl<'c> Translation<'c> { let output_local = mk().local( mk().ident_pat(&output_name), None, - Some(mk().mutbl().addr_of_expr(out_expr)), + Some(mk().mutbl().borrow_expr(out_expr)), ); stmts.push(mk().local_stmt(Box::new(output_local))); @@ -924,7 +924,7 @@ impl<'c> Translation<'c> { let mut in_expr = in_expr.into_value(); if operand.mem_only { - in_expr = mk().addr_of_expr(in_expr); + in_expr = mk().borrow_expr(in_expr); } if let Some(tied_operand) = tied_operands.get(&(input_idx, false)) { self.use_crate(ExternCrate::C2RustAsmCasts); diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index 9ce3b888dd..6ae63534a8 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -3032,7 +3032,7 @@ impl<'c> Translation<'c> { } } _ => { - let addr_lhs = mk().set_mutbl(mutbl).addr_of_expr(lhs); + let addr_lhs = mk().set_mutbl(mutbl).borrow_expr(lhs); let lhs_type = self.convert_type(lhs_type.ctype)?; let ty = mk().set_mutbl(mutbl).ptr_ty(lhs_type); @@ -4595,60 +4595,67 @@ impl<'c> Translation<'c> { .is_some() }) .unwrap_or(false); - match expr_kind { - Some(&CExprKind::Literal(_, CLiteral::String(ref bytes, 1))) - if is_const && !translate_as_macro => - { - let target_ty = self.convert_type(target_cty.ctype)?; - let mut bytes = bytes.to_owned(); - bytes.push(0); - let byte_literal = mk().lit_expr(bytes); - let val = - mk().cast_expr(byte_literal, mk().ptr_ty(mk().path_ty(vec!["u8"]))); - let val = mk().cast_expr(val, target_ty); - Ok(WithStmts::new_val(val)) - } - _ => { - // Variable length arrays are already represented as pointers. - if let CTypeKind::VariableArray(..) = source_ty_kind { - Ok(val) - } else { - let method = if is_const || ctx.is_static { - "as_ptr" - } else { - "as_mut_ptr" - }; + if let (Some(&CExprKind::Literal(_, CLiteral::String(ref bytes, 1))), true, false) = + (expr_kind, is_const, translate_as_macro) + { + let target_ty = self.convert_type(target_cty.ctype)?; + + let mut bytes = bytes.to_owned(); + bytes.push(0); + let byte_literal = mk().lit_expr(bytes); + let val = mk().cast_expr(byte_literal, mk().ptr_ty(mk().path_ty(vec!["u8"]))); + let val = mk().cast_expr(val, target_ty); + return Ok(WithStmts::new_val(val)); + } - let call = val.map(|x| mk().method_call_expr(x, method, vec![])); + // Variable length arrays are already represented as pointers. + if let CTypeKind::VariableArray(..) = source_ty_kind { + return Ok(val); + } - // If the target pointee type is different from the source element type, - // then we need to cast the ptr type as well. - let call = match source_ty_kind.element_ty() { - None => call, - Some(source_element_ty) if source_element_ty == pointee.ctype => { - call - } - Some(_) => { - let target_ty = self.convert_type(target_cty.ctype)?; - call.map(|ptr| mk().cast_expr(ptr, target_ty)) - } - }; + let (mutbl, must_cast_mut) = if is_const { + (Mutability::Immutable, false) + } else if ctx.is_static { + // TODO: The currently used nightly doesn't allow `&raw mut` in + // static initialisers, but it's allowed since version 1.83. + // So we take a `&raw const` and then cast. + // Remove `must_cast_mut` variable when the version is updated. + (Mutability::Immutable, true) + } else { + (Mutability::Mutable, false) + }; - // Static arrays can now use as_ptr. Can also cast that const ptr to a - // mutable pointer as we do here: - if ctx.is_static && !is_const { - return Ok(call.map(|val| { - let inferred_type = mk().infer_ty(); - let ptr_type = mk().mutbl().ptr_ty(inferred_type); - mk().cast_expr(val, ptr_type) - })); - } + val.result_map(|mut val| { + if translate_as_macro { + // Values that translate into temporaries can't be raw-borrowed in Rust, + // and must be regular-borrowed first. + // Borrowing in a static/const context will extend the lifetime to static. + let method = match mutbl { + Mutability::Mutable => "as_mut_ptr", + Mutability::Immutable => "as_ptr", + }; + val = mk().method_call_expr(val, method, vec![]); + } else { + self.use_feature("raw_ref_op"); + val = mk().set_mutbl(mutbl).raw_borrow_expr(val); + // TODO: Add call to `ptr::as_[mut]_ptr` once that is available + // (`array_ptr_get` feature added to nightly in January 2024) + } - Ok(call) - } + // If the target pointee type is different from the source element type, + // then we need to cast the ptr type as well. + // TODO: Remove `!translate_as_macro` when `ptr::as_[mut]_ptr` is added above. + if source_ty_kind.element_ty() != Some(pointee.ctype) + || must_cast_mut + || !translate_as_macro + { + let target_element_ty = self.convert_type(target_cty.ctype)?; + val = mk().cast_expr(val, target_element_ty); } - } + + Ok(val) + }) } CastKind::NullToPointer => { diff --git a/c2rust-transpile/src/translator/operators.rs b/c2rust-transpile/src/translator/operators.rs index cf3307bcdd..715ef634ae 100644 --- a/c2rust-transpile/src/translator/operators.rs +++ b/c2rust-transpile/src/translator/operators.rs @@ -938,54 +938,79 @@ impl<'c> Translation<'c> { // In this translation, there are only pointers to functions and // & becomes a no-op when applied to a function. - let arg = self.convert_expr(ctx.used().set_needs_address(true), arg, None)?; + let val = self.convert_expr(ctx.used().set_needs_address(true), arg, None)?; if self.ast_context.is_function_pointer(ctype) { - Ok(arg.map(|x| mk().call_expr(mk().ident_expr("Some"), vec![x]))) + return Ok(val.map(|x| mk().call_expr(mk().ident_expr("Some"), vec![x]))); + } + + let pointee_ty = + self.ast_context + .get_pointee_qual_type(ctype) + .ok_or_else(|| { + TranslationError::generic("Address-of should return a pointer") + })?; + + let translate_as_macro = self + .convert_const_macro_expansion(ctx, arg, None) + .ok() + .flatten() + .is_some(); + + let (mutbl, must_cast_mut) = if pointee_ty.qualifiers.is_const { + (Mutability::Immutable, false) + } else if ctx.is_static { + // TODO: The currently used nightly doesn't allow `&raw mut` in + // static initialisers, but it's allowed since version 1.83. + // So we take a `&raw const` and then cast. + // Remove `must_cast_mut` variable when the version is updated. + (Mutability::Immutable, true) } else { - let pointee_ty = - self.ast_context - .get_pointee_qual_type(ctype) - .ok_or_else(|| { - TranslationError::generic("Address-of should return a pointer") - })?; - - let mutbl = if pointee_ty.qualifiers.is_const { - Mutability::Immutable - } else { - Mutability::Mutable - }; + (Mutability::Mutable, false) + }; - arg.result_map(|a| { - let mut addr_of_arg: Box; - - if ctx.is_static { - // static variable initializers aren't able to use &mut, - // so we work around that by using & and an extra cast - // through & to *const to *mut - addr_of_arg = mk().addr_of_expr(a); - if let Mutability::Mutable = mutbl { - let mut qtype = pointee_ty; - qtype.qualifiers.is_const = true; - let ty_ = self - .type_converter - .borrow_mut() - .convert_pointer(&self.ast_context, qtype)?; - addr_of_arg = mk().cast_expr(addr_of_arg, ty_); - } - } else { - // Normal case is allowed to use &mut if needed - addr_of_arg = mk().set_mutbl(mutbl).addr_of_expr(a); + val.result_map(|mut val| { + if translate_as_macro + || ctx.is_static + && matches!( + arg_kind, + CExprKind::Literal(_, _) | CExprKind::CompoundLiteral(_, _) + ) + { + // Values that translate into temporaries can't be raw-borrowed in Rust, + // and must be regular-borrowed first. + // Borrowing in a static/const context will extend the lifetime to static. + val = mk().set_mutbl(mutbl).borrow_expr(val); + + // Immutable references can't be cast directly to mutable pointers, so + // add an intermediate cast to const pointer. + if must_cast_mut { + let mut const_pointee_ty = pointee_ty; + const_pointee_ty.qualifiers.is_const = true; + let const_ty = self + .type_converter + .borrow_mut() + .convert_pointer(&self.ast_context, const_pointee_ty)?; + val = mk().cast_expr(val, const_ty); + } - // Avoid unnecessary reference to pointer decay in fn call args: - if ctx.decay_ref.is_no() { - return Ok(addr_of_arg); - } + // Cast to the final pointer. + // Avoid unnecessary reference to pointer decay in fn call args. + // TODO: use `ptr::from_ref` and `ptr::from_mut` once stable (Rust 1.76). + if ctx.decay_ref.is_yes() || must_cast_mut { + val = mk().cast_expr(val, ty); } + } else { + self.use_feature("raw_ref_op"); + val = mk().set_mutbl(mutbl).raw_borrow_expr(val); - Ok(mk().cast_expr(addr_of_arg, ty)) - }) - } + if must_cast_mut { + val = mk().cast_expr(val, ty); + } + } + + Ok(val) + }) } c_ast::UnOp::PreIncrement => self.convert_pre_increment(ctx, cqual_type, true, arg), c_ast::UnOp::PreDecrement => self.convert_pre_increment(ctx, cqual_type, false, arg), diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@vm_x86.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@vm_x86.c.snap index 33ac375aa3..8eea02d366 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@vm_x86.c.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@vm_x86.c.snap @@ -11,6 +11,7 @@ input_file: c2rust-transpile/tests/snapshots/arch-specific/vm_x86.c unused_assignments, unused_mut )] +#![feature(raw_ref_op)] #[derive(Copy, Clone)] #[repr(C)] pub struct vm_t { @@ -42,17 +43,18 @@ pub unsafe extern "C" fn VM_CallCompiled( programStack -= 8 as core::ffi::c_int + 4 as core::ffi::c_int * MAX_VMMAIN_ARGS; arg = 0 as core::ffi::c_int; while arg < MAX_VMMAIN_ARGS { - *(&mut *image + *(&raw mut *image .offset((programStack + 8 as core::ffi::c_int + arg * 4 as core::ffi::c_int) as isize) - as *mut byte as *mut core::ffi::c_int) = *args.offset(arg as isize); + as *mut core::ffi::c_int) = *args.offset(arg as isize); arg += 1; } - *(&mut *image.offset((programStack + 4 as core::ffi::c_int) as isize) as *mut byte + *(&raw mut *image.offset((programStack + 4 as core::ffi::c_int) as isize) as *mut core::ffi::c_int) = 0 as core::ffi::c_int; - *(&mut *image.offset(programStack as isize) as *mut byte as *mut core::ffi::c_int) = + *(&raw mut *image.offset(programStack as isize) as *mut core::ffi::c_int) = -(1 as core::ffi::c_int); entryPoint = ((*vm).codeBase).offset((*vm).entryOfs as isize); - opStack = (stack.as_mut_ptr() as *mut core::ffi::c_int).offset(16 as core::ffi::c_int as isize); + opStack = (&raw mut stack as *mut byte as *mut core::ffi::c_int) + .offset(16 as core::ffi::c_int as isize); *opStack = 0 as core::ffi::c_int; opStackOfs = 0 as core::ffi::c_int; if opStackOfs != 1 as core::ffi::c_int diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@vm_x86.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@vm_x86.c.snap index 5819e9a938..452c9f67b8 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@vm_x86.c.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@vm_x86.c.snap @@ -11,7 +11,7 @@ input_file: c2rust-transpile/tests/snapshots/arch-specific/vm_x86.c unused_assignments, unused_mut )] -#![feature(asm)] +#![feature(asm, raw_ref_op)] use core::arch::asm; #[derive(Copy, Clone)] #[repr(C)] @@ -44,17 +44,18 @@ pub unsafe extern "C" fn VM_CallCompiled( programStack -= 8 as core::ffi::c_int + 4 as core::ffi::c_int * MAX_VMMAIN_ARGS; arg = 0 as core::ffi::c_int; while arg < MAX_VMMAIN_ARGS { - *(&mut *image + *(&raw mut *image .offset((programStack + 8 as core::ffi::c_int + arg * 4 as core::ffi::c_int) as isize) - as *mut byte as *mut core::ffi::c_int) = *args.offset(arg as isize); + as *mut core::ffi::c_int) = *args.offset(arg as isize); arg += 1; } - *(&mut *image.offset((programStack + 4 as core::ffi::c_int) as isize) as *mut byte + *(&raw mut *image.offset((programStack + 4 as core::ffi::c_int) as isize) as *mut core::ffi::c_int) = 0 as core::ffi::c_int; - *(&mut *image.offset(programStack as isize) as *mut byte as *mut core::ffi::c_int) = + *(&raw mut *image.offset(programStack as isize) as *mut core::ffi::c_int) = -(1 as core::ffi::c_int); entryPoint = ((*vm).codeBase).offset((*vm).entryOfs as isize); - opStack = (stack.as_mut_ptr() as *mut core::ffi::c_int).offset(16 as core::ffi::c_int as isize); + opStack = (&raw mut stack as *mut byte as *mut core::ffi::c_int) + .offset(16 as core::ffi::c_int as isize); *opStack = 0 as core::ffi::c_int; opStackOfs = 0 as core::ffi::c_int; asm!( diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@arrays.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@arrays.c.snap index 5d131016b8..2ce61b50d0 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@arrays.c.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@arrays.c.snap @@ -11,6 +11,7 @@ input_file: c2rust-transpile/tests/snapshots/arrays.c unused_assignments, unused_mut )] +#![feature(raw_ref_op)] #[derive(Copy, Clone)] #[repr(C)] pub struct C2RustUnnamed { @@ -78,11 +79,10 @@ pub unsafe extern "C" fn entry() { [u8; 20], [core::ffi::c_char; 20], >(*b"abc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); - let mut past_end: *mut core::ffi::c_char = &mut *simple - .as_mut_ptr() - .offset(::core::mem::size_of::<[core::ffi::c_char; 9]>() as isize) - as *mut core::ffi::c_char; - past_end = &mut *foo.offset(8 as core::ffi::c_int as isize) as *mut core::ffi::c_char; + let mut past_end: *mut core::ffi::c_char = &raw mut *(&raw mut simple + as *mut core::ffi::c_char) + .offset(::core::mem::size_of::<[core::ffi::c_char; 9]>() as isize); + past_end = &raw mut *foo.offset(8 as core::ffi::c_int as isize); } #[no_mangle] pub unsafe extern "C" fn short_initializer() { diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@atomics.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@atomics.c.snap index 3eda38f711..b2a0a0cbfa 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@atomics.c.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@atomics.c.snap @@ -11,28 +11,29 @@ input_file: c2rust-transpile/tests/snapshots/atomics.c unused_assignments, unused_mut )] -#![feature(core_intrinsics)] +#![feature(core_intrinsics, raw_ref_op)] #[no_mangle] pub unsafe extern "C" fn c11_atomics(mut x: core::ffi::c_int) -> core::ffi::c_int { - *&mut x = 0 as core::ffi::c_int; - ::core::intrinsics::atomic_store_seqcst(&mut x, 1 as core::ffi::c_int); - ::core::intrinsics::atomic_load_seqcst(&mut x); - ::core::intrinsics::atomic_xadd_seqcst(&mut x, 2 as core::ffi::c_int); - ::core::intrinsics::atomic_xsub_seqcst(&mut x, 1 as core::ffi::c_int); - ::core::intrinsics::atomic_and_seqcst(&mut x, 0xf as core::ffi::c_int); - ::core::intrinsics::atomic_or_seqcst(&mut x, 0x10 as core::ffi::c_int); - ::core::intrinsics::atomic_nand_seqcst(&mut x, 0xff as core::ffi::c_int); - ::core::intrinsics::atomic_xchg_seqcst(&mut x, 42 as core::ffi::c_int); + *&raw mut x = 0 as core::ffi::c_int; + ::core::intrinsics::atomic_store_seqcst(&raw mut x, 1 as core::ffi::c_int); + ::core::intrinsics::atomic_load_seqcst(&raw mut x); + ::core::intrinsics::atomic_xadd_seqcst(&raw mut x, 2 as core::ffi::c_int); + ::core::intrinsics::atomic_xsub_seqcst(&raw mut x, 1 as core::ffi::c_int); + ::core::intrinsics::atomic_and_seqcst(&raw mut x, 0xf as core::ffi::c_int); + ::core::intrinsics::atomic_or_seqcst(&raw mut x, 0x10 as core::ffi::c_int); + ::core::intrinsics::atomic_nand_seqcst(&raw mut x, 0xff as core::ffi::c_int); + ::core::intrinsics::atomic_xchg_seqcst(&raw mut x, 42 as core::ffi::c_int); let mut expected: core::ffi::c_int = 42 as core::ffi::c_int; let mut desired: core::ffi::c_int = 100 as core::ffi::c_int; - let fresh0 = ::core::intrinsics::atomic_cxchg_seqcst_seqcst(&mut x, *&mut expected, desired); - *&mut expected = fresh0.0; + let fresh0 = + ::core::intrinsics::atomic_cxchg_seqcst_seqcst(&raw mut x, *&raw mut expected, desired); + *&raw mut expected = fresh0.0; fresh0.1; expected = 100 as core::ffi::c_int; desired = 200 as core::ffi::c_int; let fresh1 = - ::core::intrinsics::atomic_cxchgweak_seqcst_seqcst(&mut x, *&mut expected, desired); - *&mut expected = fresh1.0; + ::core::intrinsics::atomic_cxchgweak_seqcst_seqcst(&raw mut x, *&raw mut expected, desired); + *&raw mut expected = fresh1.0; fresh1.1; return x; } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.snap index 917c9b65db..217a51f99c 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.snap @@ -11,6 +11,7 @@ input_file: c2rust-transpile/tests/snapshots/exprs.c unused_assignments, unused_mut )] +#![feature(raw_ref_op)] extern "C" { fn puts(str: *const core::ffi::c_char) -> core::ffi::c_int; } @@ -29,7 +30,7 @@ pub unsafe extern "C" fn unary_without_side_effect() { i; !i; (i == 0) as core::ffi::c_int; - &mut i; + &raw mut i; i; i += 1; i -= 1; @@ -43,10 +44,11 @@ pub unsafe extern "C" fn unary_with_side_effect() { side_effect(); !side_effect(); (side_effect() == 0) as core::ffi::c_int; - &*(b"\0" as *const u8 as *const core::ffi::c_char).offset(::core::mem::transmute::< + &raw const *(b"\0" as *const u8 as *const core::ffi::c_char).offset(::core::mem::transmute::< unsafe extern "C" fn() -> core::ffi::c_int, unsafe extern "C" fn() -> core::ffi::c_int, - >(side_effect)() as isize) as *const core::ffi::c_char; + >(side_effect)() + as isize); *arr[side_effect() as usize]; arr[side_effect() as usize] = (arr[side_effect() as usize]).offset(1); arr[side_effect() as usize] = (arr[side_effect() as usize]).offset(-1); diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.snap index a373790485..3ba3f8c231 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.snap @@ -11,6 +11,7 @@ input_file: c2rust-transpile/tests/snapshots/macros.c unused_assignments, unused_mut )] +#![feature(raw_ref_op)] extern "C" { fn extern_fn() -> core::ffi::c_int; } @@ -104,10 +105,9 @@ pub unsafe extern "C" fn local_muts() { let mut str_concatenation: [core::ffi::c_char; 18] = ::core::mem::transmute::<[u8; 18], [core::ffi::c_char; 18]>(*b"hello hello world\0"); let mut builtin: core::ffi::c_int = (LITERAL_INT as core::ffi::c_uint).leading_zeros() as i32; - let mut ref_indexing: *const core::ffi::c_char = &*NESTED_STR + let mut ref_indexing: *const core::ffi::c_char = &raw const *NESTED_STR .as_ptr() - .offset(LITERAL_FLOAT as core::ffi::c_int as isize) - as *const core::ffi::c_char; + .offset(LITERAL_FLOAT as core::ffi::c_int as isize); let mut ref_struct: *const S = &mut LITERAL_STRUCT as *mut S; let mut ternary: core::ffi::c_int = if LITERAL_BOOL != 0 { 1 as core::ffi::c_int @@ -173,10 +173,9 @@ pub unsafe extern "C" fn local_consts() { let str_concatenation: [core::ffi::c_char; 18] = ::core::mem::transmute::<[u8; 18], [core::ffi::c_char; 18]>(*b"hello hello world\0"); let builtin: core::ffi::c_int = (LITERAL_INT as core::ffi::c_uint).leading_zeros() as i32; - let ref_indexing: *const core::ffi::c_char = &*NESTED_STR + let ref_indexing: *const core::ffi::c_char = &raw const *NESTED_STR .as_ptr() - .offset(LITERAL_FLOAT as core::ffi::c_int as isize) - as *const core::ffi::c_char; + .offset(LITERAL_FLOAT as core::ffi::c_int as isize); let ref_struct: *const S = &mut LITERAL_STRUCT as *mut S; let ternary: core::ffi::c_int = if LITERAL_BOOL != 0 { 1 as core::ffi::c_int @@ -357,7 +356,7 @@ pub static mut fns: fn_ptrs = { init }; #[no_mangle] -pub static mut p: *const fn_ptrs = unsafe { &fns as *const fn_ptrs }; +pub static mut p: *const fn_ptrs = unsafe { &raw const fns }; pub const ZSTD_WINDOWLOG_MAX_32: core::ffi::c_int = 30 as core::ffi::c_int; pub const ZSTD_WINDOWLOG_MAX_64: core::ffi::c_int = 31 as core::ffi::c_int; #[no_mangle] @@ -371,7 +370,7 @@ pub unsafe extern "C" fn test_zstd() -> U64 { #[no_mangle] pub unsafe extern "C" fn stmt_expr_inc() -> core::ffi::c_int { let mut a: core::ffi::c_int = 0 as core::ffi::c_int; - let mut b: *mut core::ffi::c_int = &mut a; + let mut b: *mut core::ffi::c_int = &raw mut a; ({ *b += 1; *b; @@ -432,10 +431,9 @@ pub unsafe extern "C" fn late_init_var() -> core::ffi::c_int { unsafe extern "C" fn run_static_initializers() { global_static_const_ptr_arithmetic = PTR_ARITHMETIC; global_static_const_indexing = NESTED_STR[LITERAL_FLOAT as core::ffi::c_int as usize]; - global_static_const_ref_indexing = &*NESTED_STR + global_static_const_ref_indexing = &raw const *NESTED_STR .as_ptr() - .offset(LITERAL_FLOAT as core::ffi::c_int as isize) - as *const core::ffi::c_char; + .offset(LITERAL_FLOAT as core::ffi::c_int as isize); global_static_const_ternary = if LITERAL_BOOL != 0 { 1 as core::ffi::c_int } else { @@ -444,10 +442,9 @@ unsafe extern "C" fn run_static_initializers() { global_static_const_member = LITERAL_STRUCT.i; global_const_ptr_arithmetic = PTR_ARITHMETIC; global_const_indexing = NESTED_STR[LITERAL_FLOAT as core::ffi::c_int as usize]; - global_const_ref_indexing = &*NESTED_STR + global_const_ref_indexing = &raw const *NESTED_STR .as_ptr() - .offset(LITERAL_FLOAT as core::ffi::c_int as isize) - as *const core::ffi::c_char; + .offset(LITERAL_FLOAT as core::ffi::c_int as isize); global_const_ternary = if LITERAL_BOOL != 0 { 1 as core::ffi::c_int } else { diff --git a/tests/arrays/src/test_arrays.rs b/tests/arrays/src/test_arrays.rs index 82479cf867..e71b408651 100644 --- a/tests/arrays/src/test_arrays.rs +++ b/tests/arrays/src/test_arrays.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + use crate::arrays::rust_entry; use crate::incomplete_arrays::{rust_check_some_ints, rust_entry2, rust_test_sized_array}; use crate::variable_arrays::{rust_alloca_arrays, rust_variable_arrays}; diff --git a/tests/builtins/src/test_builtins.rs b/tests/builtins/src/test_builtins.rs index de82132ba6..b552f86309 100644 --- a/tests/builtins/src/test_builtins.rs +++ b/tests/builtins/src/test_builtins.rs @@ -1,4 +1,4 @@ -//! feature_core_intrinsics +//! feature_core_intrinsics, feature_raw_ref_op use crate::alloca::rust_alloca_hello; use crate::atomics::{rust_atomics_entry, rust_new_atomics}; diff --git a/tests/casts/src/test_casts.rs b/tests/casts/src/test_casts.rs index bad9ccd9dc..1d13d37c97 100644 --- a/tests/casts/src/test_casts.rs +++ b/tests/casts/src/test_casts.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + use crate::cast_funptr::{rust_entry, rust_get_identity, rust_identity}; use crate::casts::rust_cast_stuff; diff --git a/tests/conditionals/src/test_conditionals.rs b/tests/conditionals/src/test_conditionals.rs index 2353217677..d18af7666e 100644 --- a/tests/conditionals/src/test_conditionals.rs +++ b/tests/conditionals/src/test_conditionals.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + use crate::binary_conditional::rust_entry3; use crate::conditional::rust_entry; use crate::conditionals::{rust_entry2, rust_ternaries}; diff --git a/tests/ints/src/test_arithmetic.rs b/tests/ints/src/test_arithmetic.rs index dc3397271a..2cb0a61bd7 100644 --- a/tests/ints/src/test_arithmetic.rs +++ b/tests/ints/src/test_arithmetic.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + use crate::arithmetic::rust_entry2; use std::ffi::{c_int, c_uint}; diff --git a/tests/items/src/test_varargs.rs b/tests/items/src/test_varargs.rs index 8c9d23469d..01422c6f05 100644 --- a/tests/items/src/test_varargs.rs +++ b/tests/items/src/test_varargs.rs @@ -1,4 +1,4 @@ -//! feature_c_variadic, +//! feature_c_variadic, feature_raw_ref_op use crate::varargs::rust_call_printf; // See #1281. Varargs don't yet work on aarch64. diff --git a/tests/macros/src/test_define.rs b/tests/macros/src/test_define.rs index 9a38fd724a..39d37ae4cd 100644 --- a/tests/macros/src/test_define.rs +++ b/tests/macros/src/test_define.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + use crate::define::{rust_fns, rust_stmt_expr_inc}; use crate::define::{rust_reference_define, TEST_CONST1, TEST_CONST2, TEST_PARENS}; use crate::define::{rust_test_zstd, ZSTD_WINDOWLOG_MAX_32, ZSTD_WINDOWLOG_MAX_64}; diff --git a/tests/misc/src/test_exprs.rs b/tests/misc/src/test_exprs.rs index 04555acbda..32e66235d0 100644 --- a/tests/misc/src/test_exprs.rs +++ b/tests/misc/src/test_exprs.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + use crate::exprs::rust_exprs; use std::ffi::{c_int, c_uint}; diff --git a/tests/misc/src/test_quicksort.rs b/tests/misc/src/test_quicksort.rs index d5a09a0ecc..c06da72a8c 100644 --- a/tests/misc/src/test_quicksort.rs +++ b/tests/misc/src/test_quicksort.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + use crate::qsort::{rust_partition, rust_quickSort, rust_swap}; use std::ffi::c_int; diff --git a/tests/misc/src/test_sizeofs.rs b/tests/misc/src/test_sizeofs.rs index 262235100b..88840d15d3 100644 --- a/tests/misc/src/test_sizeofs.rs +++ b/tests/misc/src/test_sizeofs.rs @@ -1,4 +1,4 @@ -//! feature_core_intrinsics, feature_label_break_value +//! feature_core_intrinsics, feature_label_break_value, feature_raw_ref_op use crate::sizeofs::rust_sizeofs; use std::ffi::{c_int, c_uint}; diff --git a/tests/misc/src/test_typedef.rs b/tests/misc/src/test_typedef.rs index 812e209f4d..be9f5f2e3f 100644 --- a/tests/misc/src/test_typedef.rs +++ b/tests/misc/src/test_typedef.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + use crate::typedef::{int_ptr, my_int, rust_entry}; use std::ffi::c_int; diff --git a/tests/misc/src/test_uninitialized.rs b/tests/misc/src/test_uninitialized.rs index 005aac15ac..390ac74b95 100644 --- a/tests/misc/src/test_uninitialized.rs +++ b/tests/misc/src/test_uninitialized.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + use crate::uninitialized::{bar, baz, e, foo, rust_entry2, s, /*myint, myintp,*/ u}; use std::ffi::{c_int, c_uint}; diff --git a/tests/pointers/src/test_pointers.rs b/tests/pointers/src/test_pointers.rs index 7793e48477..6a95f04988 100644 --- a/tests/pointers/src/test_pointers.rs +++ b/tests/pointers/src/test_pointers.rs @@ -1,4 +1,4 @@ -//! feature_c_variadic +//! feature_c_variadic, feature_raw_ref_op use crate::function_pointers::rust_entry3; use crate::pointer_arith::rust_entry2; diff --git a/tests/statics/src/test_sections.rs b/tests/statics/src/test_sections.rs index 2c74c94267..09c8d5774e 100644 --- a/tests/statics/src/test_sections.rs +++ b/tests/statics/src/test_sections.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + #[cfg(not(target_os = "macos"))] use crate::attributes::{rust_no_attrs, rust_used_static, rust_used_static2, rust_used_static3}; use crate::sections::*; diff --git a/tests/structs/src/test_flex_array_members.rs b/tests/structs/src/test_flex_array_members.rs index a679bd2dc4..ec28c5fa28 100644 --- a/tests/structs/src/test_flex_array_members.rs +++ b/tests/structs/src/test_flex_array_members.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + use crate::flex_array_members::rust_exercise_flex_arrays; use std::ffi::{c_int, c_uint}; diff --git a/tests/structs/src/test_struct_with_exp.rs b/tests/structs/src/test_struct_with_exp.rs index 18f8a47567..0d9ffb464b 100644 --- a/tests/structs/src/test_struct_with_exp.rs +++ b/tests/structs/src/test_struct_with_exp.rs @@ -1,3 +1,5 @@ +//! feature_raw_ref_op + use crate::struct_with_exp::rust_struct_with_exp; use std::ffi::{c_int, c_uint};