diff --git a/c2rust-ast-exporter/src/AstExporter.cpp b/c2rust-ast-exporter/src/AstExporter.cpp index 87e56b481e..0aa6ecb09a 100644 --- a/c2rust-ast-exporter/src/AstExporter.cpp +++ b/c2rust-ast-exporter/src/AstExporter.cpp @@ -1426,65 +1426,106 @@ class TranslateASTVisitor final LLVM_DEBUG(Range.getBegin().dump(Mgr)); LLVM_DEBUG(Range.getEnd().dump(Mgr)); - auto Begin = Range.getBegin(); - auto End = Range.getEnd(); - - // Check that we are only expanding a single macro call. - if (!Begin.isMacroID() || !End.isMacroID() || - Mgr.getImmediateMacroCallerLoc(Begin) != Mgr.getImmediateMacroCallerLoc(End)) + if (!Range.getBegin().isMacroID() || !Range.getEnd().isMacroID()) { return true; + } - if (Begin.isMacroID()) { -#if CLANG_VERSION_MAJOR < 7 - // getImmediateExpansionRange in LLVM<7 returns a - // std::pair, which we need to - // translate to a CharSourceRange for Lexer::getSourceText - auto LocPair = Mgr.getImmediateExpansionRange(Begin); - auto ExpansionRange = CharSourceRange::getCharRange(LocPair.first, LocPair.second); -#else // CLANG_VERSION_MAJOR >= 7 - auto ExpansionRange = Mgr.getImmediateExpansionRange(Begin); -#endif - curMacroExpansionSource = - Lexer::getSourceText(ExpansionRange, Mgr, Context->getLangOpts()); + // Holds the stack of ranges of macro expansions that expand to this expression. + // The last element is the top-level macro call. + auto ExpansionStack = getMacroExpansionStack(Range); + + if (ExpansionStack.empty()) { + return true; } - // The macro stack unwound by getImmediateMacroCallerLoc and friends - // starts with literal replacement and works it's way to the macro call - // that was replaced. - while (Begin.isMacroID()) { -#if CLANG_VERSION_MAJOR < 7 - auto ExpansionRange = Mgr.getImmediateExpansionRange(Begin); - auto ExpansionBegin = ExpansionRange.first; - auto ExpansionEnd = ExpansionRange.second; -#else // CLANG_VERSION_MAJOR >= 7 - auto ExpansionRange = Mgr.getImmediateExpansionRange(Begin).getAsRange(); - auto ExpansionBegin = ExpansionRange.getBegin(); - auto ExpansionEnd = ExpansionRange.getEnd(); -#endif + curMacroExpansionSource = + Lexer::getSourceText(ExpansionStack[0], Mgr, Context->getLangOpts()); + + for (auto &ExpansionRange : ExpansionStack) { StringRef name; - MacroInfo *mac = getMacroInfo(ExpansionBegin, name); + MacroInfo *mac = getMacroInfo(ExpansionRange.getBegin(), name); - if (!mac || mac->getNumTokens() == 0) + if (!mac || mac->getNumTokens() == 0) { return true; - auto ReplacementBegin = mac->getReplacementToken(0).getLocation(); - auto ReplacementEnd = mac->getDefinitionEndLoc(); - // Verify that this expansion covers the entire macro replacement - // definition, i.e. E is not a subexpression of the macro - // replacement. - if (Mgr.getSpellingLoc(Begin) != ReplacementBegin || - Mgr.getSpellingLoc(End) != ReplacementEnd) - return true; - - Begin = ExpansionBegin; - End = ExpansionEnd; + } - if (VisitMacro(name, Begin, mac, E)) { + if (VisitMacro(name, ExpansionRange.getBegin(), mac, E)) { curMacroExpansionStack.push_back(mac); } } + return true; } + std::vector getMacroExpansionStack(SourceRange Range) const { + auto &Mgr = Context->getSourceManager(); + auto Begin = Range.getBegin(); + auto End = Range.getEnd(); + std::vector ExpansionStack; + + do { + if (!isAtStartOfImmediateMacroExpansion(Begin)) { + break; + } + + auto ExpansionRange = Mgr.getImmediateExpansionRange(Begin); + ExpansionStack.push_back(ExpansionRange); + Begin = ExpansionRange.getBegin(); + } while (Begin.isMacroID()); + + // Find the point at which `Begin` and `End` converge on the same expansion range. + // This is where the expression in `Range` first corresponds to a single macro call. + auto ConvergencePoint = ExpansionStack.end(); + + do { + if (!isAtEndOfImmediateMacroExpansion(End)) { + break; + } + + auto ExpansionRange = Mgr.getImmediateExpansionRange(End); + ConvergencePoint = std::find_if( + ExpansionStack.begin(), + ExpansionStack.end(), + [ExpansionRange](auto &R) { + return R.getAsRange() == ExpansionRange.getAsRange() && + R.isTokenRange() == ExpansionRange.isTokenRange(); + } + ); + End = ExpansionRange.getEnd(); + } while (End.isMacroID() && ConvergencePoint == ExpansionStack.end()); + + // Remove all elements before the convergence point. + ExpansionStack.erase(ExpansionStack.begin(), ConvergencePoint); + + // Ensure the remaining ranges still correspond to the input `Range`. + auto EraseAfter = std::find_if( + ExpansionStack.begin(), + ExpansionStack.end(), + [this](auto &R) { + auto End = R.getEnd(); + return End.isMacroID() && !isAtEndOfImmediateMacroExpansion(End); + } + ); + auto EraseFrom = EraseAfter + 1; + + if (EraseFrom < ExpansionStack.end()) { + ExpansionStack.erase(EraseFrom, ExpansionStack.end()); + } + + return ExpansionStack; + } + + bool isAtStartOfImmediateMacroExpansion(SourceLocation loc) const { + auto &Mgr = Context->getSourceManager(); + return Mgr.isAtStartOfImmediateMacroExpansion(loc); + } + + bool isAtEndOfImmediateMacroExpansion(SourceLocation loc) const { + auto &Mgr = Context->getSourceManager(); + auto spellingLoc = Mgr.getSpellingLoc(loc); + auto len = Lexer::MeasureTokenLength(spellingLoc, Mgr, Context->getLangOpts()); + return Mgr.isAtEndOfImmediateMacroExpansion(loc.getLocWithOffset(len)); + } bool VisitVAArgExpr(VAArgExpr *E) { std::vector childIds{E->getSubExpr()}; diff --git a/c2rust-transpile/src/c_ast/conversion.rs b/c2rust-transpile/src/c_ast/conversion.rs index 4a3acb0725..e6e7225491 100644 --- a/c2rust-transpile/src/c_ast/conversion.rs +++ b/c2rust-transpile/src/c_ast/conversion.rs @@ -503,6 +503,28 @@ impl ConversionContext { self.visit_node(untyped_context, node_id, new_id, expected_ty) } + // Check what primitive kinds were emitted by the compiler. + let mut found_kinds: HashMap<_, _> = CTypeKind::PRIMITIVE_KINDS + .into_iter() + .map(|kind| (kind, false)) + .collect(); + + for Located { kind, .. } in self.typed_context.c_types.values() { + if let Some(is_found) = found_kinds.get_mut(kind) { + *is_found = true; + } + } + + // If any primitives are missing, add them ourselves. + for (kind, is_found) in found_kinds { + if !is_found { + let new_id = self.id_mapper.fresh_id(); + self.add_type(new_id, not_located(kind)); + self.processed_nodes + .insert(new_id, self::node_types::OTHER_TYPE); + } + } + // Function declarations' types look through typedefs, but we want to use the types with // typedefs intact in some cases during translation. To ensure that these types exist in the // `TypedAstContext`, iterate over all function decls, compute their adjusted type using @@ -511,7 +533,7 @@ impl ConversionContext { for (_decl_id, located_kind) in self.typed_context.c_decls.iter() { if let kind @ CDeclKind::Function { .. } = &located_kind.kind { let new_kind = self.typed_context.fn_decl_ty_with_declared_args(kind); - if self.typed_context.type_for_kind(&new_kind).is_none() { + if self.typed_context.try_type_for_kind(&new_kind).is_none() { // Create and insert fn type let new_id = CTypeId(self.id_mapper.fresh_id()); self.typed_context @@ -2203,9 +2225,7 @@ impl ConversionContext { } }; log::trace!("Selected kind {kind} for typedef {name}"); - Some(CQualTypeId::new( - self.typed_context.type_for_kind(&kind).unwrap(), - )) + Some(CQualTypeId::new(self.typed_context.type_for_kind(&kind))) }) .unwrap_or(typ); @@ -2248,9 +2268,7 @@ impl ConversionContext { } }; log::trace!("Selected kind {kind} for typedef {name}"); - Some(CQualTypeId::new( - self.typed_context.type_for_kind(&kind).unwrap(), - )) + Some(CQualTypeId::new(self.typed_context.type_for_kind(&kind))) }; let file = self .typed_context diff --git a/c2rust-transpile/src/c_ast/mod.rs b/c2rust-transpile/src/c_ast/mod.rs index 2b8a76e608..80976ee2bd 100644 --- a/c2rust-transpile/src/c_ast/mod.rs +++ b/c2rust-transpile/src/c_ast/mod.rs @@ -1,5 +1,6 @@ use crate::c_ast::iterators::{immediate_children_all_types, NodeVisitor}; use crate::iterators::{DFNodes, SomeId}; +use c2rust_ast_builder::properties::Mutability; use c2rust_ast_exporter::clang_ast::LRValue; use indexmap::{IndexMap, IndexSet}; use itertools::Itertools; @@ -777,12 +778,17 @@ impl TypedAstContext { ty.map(|ty| (expr_id, ty)) } - pub fn type_for_kind(&self, kind: &CTypeKind) -> Option { + pub fn try_type_for_kind(&self, kind: &CTypeKind) -> Option { self.c_types .iter() .find_map(|(id, k)| if kind == &k.kind { Some(*id) } else { None }) } + pub fn type_for_kind(&self, kind: &CTypeKind) -> CTypeId { + self.try_type_for_kind(kind) + .expect("could not find type for CTypeKind::{kind:?}") + } + pub fn resolve_type_id(&self, typ: CTypeId) -> CTypeId { use CTypeKind::*; let ty = match self.index(typ).kind { @@ -881,9 +887,7 @@ impl TypedAstContext { pub fn fn_declref_ty_with_declared_args(&self, func_expr: CExprId) -> Option { if let Some(func_decl @ CDeclKind::Function { .. }) = self.fn_declref_decl(func_expr) { let kind_with_declared_args = self.fn_decl_ty_with_declared_args(func_decl); - let specific_typ = self - .type_for_kind(&kind_with_declared_args) - .unwrap_or_else(|| panic!("no type for kind {kind_with_declared_args:?}")); + let specific_typ = self.type_for_kind(&kind_with_declared_args); return Some(CQualTypeId::new(specific_typ)); } None @@ -1383,10 +1387,7 @@ impl TypedAstContext { CUnTypeOp::AlignOf => CTypeKind::Size, CUnTypeOp::PreferredAlignOf => CTypeKind::Size, }; - let ty = self - .ast_context - .type_for_kind(&kind) - .expect("CTypeKind::Size should be size_t"); + let ty = self.ast_context.type_for_kind(&kind); Some(CQualTypeId::new(ty)) } _ => return, @@ -2101,7 +2102,7 @@ impl CUnOp { } Not => { return ast_context - .type_for_kind(&CTypeKind::Int) + .try_type_for_kind(&CTypeKind::Int) .map(CQualTypeId::new) } Real | Imag => { @@ -2483,7 +2484,7 @@ pub struct AsmOperand { } /// Type qualifiers (6.7.3) -#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash)] pub struct Qualifiers { /// The `const` qualifier, which marks lvalues as non-assignable. /// @@ -2516,10 +2517,17 @@ impl Qualifiers { is_volatile: self.is_volatile || other.is_volatile, } } + + pub fn mutability(self) -> Mutability { + match self.is_const { + true => Mutability::Immutable, + false => Mutability::Mutable, + } + } } /// Qualified type -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct CQualTypeId { pub qualifiers: Qualifiers, pub ctype: CTypeId, @@ -2536,6 +2544,10 @@ impl CQualTypeId { pub fn with_ctype(self, ctype: CTypeId) -> Self { Self { ctype, ..self } } + + pub fn mutability(self) -> Mutability { + self.qualifiers.mutability() + } } // TODO: these may be interesting, but I'm not sure if they fit here: @@ -2546,7 +2558,7 @@ impl CQualTypeId { /// Represents a type in C (6.2.5 Types) /// /// Reflects the types in -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum CTypeKind { Void, @@ -2670,6 +2682,17 @@ pub enum CTypeKind { } impl CTypeKind { + /// Kinds for C primitive types. These are emitted by the compiler, but possibly only if + /// they are actually used in the code. + pub const PRIMITIVE_KINDS: [CTypeKind; 16] = { + use CTypeKind::*; + [ + Void, Bool, Char, SChar, Short, Int, Long, LongLong, UChar, UShort, UInt, ULong, + ULongLong, Float, Double, LongDouble, + ] + }; + + /// Kinds for Rust types that are pulled back into C, for more fine-grained translation. pub const PULLBACK_KINDS: [CTypeKind; 16] = { use CTypeKind::*; [ diff --git a/c2rust-transpile/src/convert_type.rs b/c2rust-transpile/src/convert_type.rs index 05fd52b148..d05e281b6f 100644 --- a/c2rust-transpile/src/convert_type.rs +++ b/c2rust-transpile/src/convert_type.rs @@ -5,7 +5,7 @@ use crate::renamer::*; use crate::translator::variadic::mk_va_list_ty; use crate::TranspilerConfig; use crate::{CrateSet, ExternCrate}; -use c2rust_ast_builder::{mk, properties::*}; +use c2rust_ast_builder::mk; use c2rust_rust_tools::RustEdition; use failure::format_err; use indexmap::IndexSet; @@ -170,13 +170,7 @@ impl TypeConverter { let param = mk().angle_bracketed_args(vec![pointee_ty]); Ok(mk().path_ty(vec![mk().path_segment_with_args("Option", param)])) } else { - let mutbl = if qtype.qualifiers.is_const { - Mutability::Immutable - } else { - Mutability::Mutable - }; - - Ok(mk().set_mutbl(mutbl).ptr_ty(pointee_ty)) + Ok(mk().set_mutbl(qtype.mutability()).ptr_ty(pointee_ty)) } } diff --git a/c2rust-transpile/src/translator/functions.rs b/c2rust-transpile/src/translator/functions.rs index bedff5e479..a3582d4638 100644 --- a/c2rust-transpile/src/translator/functions.rs +++ b/c2rust-transpile/src/translator/functions.rs @@ -341,11 +341,7 @@ impl<'c> Translation<'c> { typ: CQualTypeId, ) -> TranslationResult { if self.ast_context.is_va_list(typ.ctype) { - let mutbl = if typ.qualifiers.is_const { - Mutability::Immutable - } else { - Mutability::Mutable - }; + let mutbl = typ.mutability(); let ty = mk().abs_path_ty(vec!["core", "ffi", "VaList"]); return Ok(ConvertedFunctionParam { mutbl, ty }); } diff --git a/c2rust-transpile/src/translator/literals.rs b/c2rust-transpile/src/translator/literals.rs index 5140cd014c..afa003d0f5 100644 --- a/c2rust-transpile/src/translator/literals.rs +++ b/c2rust-transpile/src/translator/literals.rs @@ -193,13 +193,8 @@ impl<'c> Translation<'c> { })) } else { Ok(val.and_then(|val| { - let mutbl = if qty.qualifiers.is_const { - Mutability::Immutable - } else { - Mutability::Mutable - }; let local = mk().local( - mk().set_mutbl(mutbl).ident_pat(&fresh_name), + mk().set_mutbl(qty.mutability()).ident_pat(&fresh_name), Some(fresh_ty), Some(val), ); diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index 881e1037d4..b858dbd838 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -2735,11 +2735,7 @@ impl<'c> Translation<'c> { self.convert_type(typ.ctype)? }; - let mutbl = if typ.qualifiers.is_const { - Mutability::Immutable - } else { - Mutability::Mutable - }; + let mutbl = typ.mutability(); Ok(ConvertedVariable { ty, mutbl, init }) } @@ -3190,7 +3186,7 @@ impl<'c> Translation<'c> { if let Some(ty) = self .ast_context - .type_for_kind(&kind_with_declared_args) + .try_type_for_kind(&kind_with_declared_args) .map(CQualTypeId::new) { let ty = self.convert_type(ty.ctype)?; @@ -3679,14 +3675,10 @@ impl<'c> Translation<'c> { // precise source type. The AST node's type will not preserve typedef arg types // but the function's declaration will. let kind_with_declared_args = self.ast_context.fn_decl_ty_with_declared_args(func_decl); - let func_ty = self - .ast_context - .type_for_kind(&kind_with_declared_args) - .unwrap_or_else(|| panic!("no type for kind {kind_with_declared_args:?}")); + let func_ty = self.ast_context.type_for_kind(&kind_with_declared_args); let func_ptr_ty = self .ast_context - .type_for_kind(&CTypeKind::Pointer(CQualTypeId::new(func_ty))) - .unwrap_or_else(|| panic!("no type for kind {kind_with_declared_args:?}")); + .type_for_kind(&CTypeKind::Pointer(CQualTypeId::new(func_ty))); CQualTypeId::new(func_ptr_ty) } else { diff --git a/c2rust-transpile/src/translator/operators.rs b/c2rust-transpile/src/translator/operators.rs index a61eac8cdd..00cdc20af5 100644 --- a/c2rust-transpile/src/translator/operators.rs +++ b/c2rust-transpile/src/translator/operators.rs @@ -632,11 +632,7 @@ impl<'c> Translation<'c> { let one_type_id = if let CTypeKind::Pointer(..) = self.ast_context.resolve_type(arg_type.ctype).kind { - CQualTypeId::new( - self.ast_context - .type_for_kind(&CTypeKind::Int) - .ok_or_else(|| format_err!("couldn't find type for CTypeKind::Int"))?, - ) + CQualTypeId::new(self.ast_context.type_for_kind(&CTypeKind::Int)) } else { arg_type }; diff --git a/c2rust-transpile/src/translator/pointers.rs b/c2rust-transpile/src/translator/pointers.rs index 5428ce9e6b..884b36926c 100644 --- a/c2rust-transpile/src/translator/pointers.rs +++ b/c2rust-transpile/src/translator/pointers.rs @@ -1,5 +1,6 @@ use c2rust_ast_builder::{mk, properties::Mutability}; use c2rust_ast_exporter::clang_ast::LRValue; +use c2rust_rust_tools::RustEdition; use failure::{err_msg, format_err}; use syn::{BinOp, Expr, Type, UnOp}; @@ -108,16 +109,14 @@ impl<'c> Translation<'c> { let mut needs_cast = false; let mut ref_cast_pointee_ty = None; - let mutbl = if pointee_cty.qualifiers.is_const { - Mutability::Immutable - } else if ctx.is_const { + let mutbl = if ctx.is_const && !pointee_cty.qualifiers.is_const { // const contexts aren't able to use &mut, so we work around that // by using & and an extra cast through & to *const to *mut // TODO: Rust 1.83: Allowed, so this can be removed. needs_cast = true; Mutability::Immutable } else { - Mutability::Mutable + pointee_cty.mutability() }; // Narrow string literals are translated directly as `[u8; N]` literals when their address @@ -485,17 +484,68 @@ impl<'c> Translation<'c> { WithStmts::new_val(transmute_expr(intptr_t, target_ty, val)).set_unsafe() })) - } else if source_ty_kind.is_bool() { - self.use_crate(ExternCrate::Libc); - Ok(val.map(|mut val| { - // First cast the boolean to pointer size - val = mk().cast_expr(val, mk().abs_path_ty(vec!["libc", "size_t"])); - mk().cast_expr(val, target_ty) - })) - } else if let &CTypeKind::Enum(..) = source_ty_kind { - val.try_map(|val| self.convert_cast_from_enum(target_cty, val)) + } + // Rust 1.90: `const_strict_provenance` feature added + // Rust 1.91: stabilized + else if ctx.is_const && self.tcfg.edition < RustEdition::Edition2024 { + if source_ty_kind.is_bool() { + self.use_crate(ExternCrate::Libc); + Ok(val.map(|mut val| { + // First cast the boolean to pointer size + val = mk().cast_expr(val, mk().abs_path_ty(vec!["libc", "size_t"])); + mk().cast_expr(val, target_ty) + })) + } else if let &CTypeKind::Enum(..) = source_ty_kind { + val.try_map(|val| self.convert_cast_from_enum(target_cty, val)) + } else { + Ok(val.map(|val| mk().cast_expr(val, target_ty))) + } } else { - Ok(val.map(|val| mk().cast_expr(val, target_ty))) + // First cast the value to `usize`. + let source_type_kind = &self.ast_context.resolve_type(source_cty).kind; + let size_type_id = self.ast_context.type_for_kind(&CTypeKind::Size); + + let val = if let &CTypeKind::Enum(..) = source_type_kind { + val.try_map(|val| self.convert_cast_from_enum(size_type_id, val))? + } else { + let size_type_rs = self.convert_type(size_type_id)?; + val.map(|val| mk().cast_expr(val, size_type_rs)) + }; + + // Then convert the `usize` into a pointer. + let pointee_type_id = self + .ast_context + .get_pointee_qual_type(target_cty) + .expect("target type must be a pointer"); + let mutability = pointee_type_id.mutability(); + + let fn_name = match self.tcfg.edition { + RustEdition::Edition2021 => { + // Rust 1.76: feature name changed to `exposed_provenance[_mut]` + // Rust 1.84: stabilized + self.use_feature("strict_provenance"); + + // Rust 1.79: method name changed to `with_exposed_provenance[_mut]` + match mutability { + Mutability::Immutable => "from_exposed_addr", + Mutability::Mutable => "from_exposed_addr_mut", + } + } + RustEdition::Edition2024 => match mutability { + Mutability::Immutable => "with_exposed_provenance", + Mutability::Mutable => "with_exposed_provenance_mut", + }, + }; + let pointee_type_rs = self.convert_pointee_type(pointee_type_id.ctype)?; + let type_args = mk().angle_bracketed_args(vec![pointee_type_rs]); + let fn_expr = mk().abs_path_expr(vec![ + mk().path_segment("core"), + mk().path_segment("ptr"), + mk().path_segment_with_args(fn_name, type_args), + ]); + let val = val.map(|val| mk().call_expr(fn_expr, vec![val])); + + Ok(val) } } @@ -514,18 +564,40 @@ impl<'c> Translation<'c> { )); } - let target_ty = self.convert_type(target_cty)?; - let source_ty = self.convert_type(source_cty)?; - let target_ty_kind = &self.ast_context.resolve_type(target_cty).kind; + let target_type_rs = self.convert_type(target_cty)?; if self.ast_context.is_function_pointer(source_cty) { + let source_ty = self.convert_type(source_cty)?; + Ok(val.and_then(|val| { - WithStmts::new_val(transmute_expr(source_ty, target_ty, val)).set_unsafe() + WithStmts::new_val(transmute_expr(source_ty, target_type_rs, val)).set_unsafe() })) - } else if let &CTypeKind::Enum(enum_decl_id) = target_ty_kind { - val.try_map(|val| self.convert_cast_to_enum(ctx, target_cty, enum_decl_id, expr, val)) } else { - Ok(val.map(|val| mk().cast_expr(val, target_ty))) + // First convert the pointer to `usize`. + let method_name = match self.tcfg.edition { + RustEdition::Edition2021 => { + // Rust 1.76: feature name changed to `exposed_provenance` + // Rust 1.84: stabilized + self.use_feature("strict_provenance"); + + // Rust 1.79: method name changed to `expose_provenance` + "expose_addr" + } + RustEdition::Edition2024 => "expose_provenance", + }; + + let val = val.map(|val| mk().method_call_expr(val, method_name, vec![])); + + // Then cast the `usize` to the target type. + let target_ty_kind = &self.ast_context.resolve_type(target_cty).kind; + + if let &CTypeKind::Enum(enum_decl_id) = target_ty_kind { + val.try_map(|val| { + self.convert_cast_to_enum(ctx, target_cty, enum_decl_id, expr, val) + }) + } else { + Ok(val.map(|val| mk().cast_expr(val, target_type_rs))) + } } } diff --git a/c2rust-transpile/src/translator/variadic.rs b/c2rust-transpile/src/translator/variadic.rs index 66c7a313fa..801b129777 100644 --- a/c2rust-transpile/src/translator/variadic.rs +++ b/c2rust-transpile/src/translator/variadic.rs @@ -199,12 +199,7 @@ impl<'c> Translation<'c> { is_variadic, )?; - let m = if p.qualifiers.is_const { - Mutability::Immutable - } else { - Mutability::Mutable - }; - Some(mk().set_mutbl(m).ptr_ty(fn_ty)) + Some(mk().set_mutbl(p.mutability()).ptr_ty(fn_ty)) } else { None } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap index b059b1a47f..3f8ff8ab44 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap @@ -58,6 +58,11 @@ pub const NESTED_CHAR: ::core::ffi::c_int = LITERAL_CHAR; pub const NESTED_STR: [::core::ffi::c_char; 6] = LITERAL_STR; pub const NESTED_ARRAY: [::core::ffi::c_int; 3] = LITERAL_ARRAY; pub const NESTED_STRUCT: S = LITERAL_STRUCT; +pub const NEGATIVE_INT: ::core::ffi::c_int = -LITERAL_INT; +pub const INT_ARITHMETIC: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +pub const MIXED_ARITHMETIC: ::core::ffi::c_double = LITERAL_INT as ::core::ffi::c_double + + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double + - true_0 as ::core::ffi::c_double; pub const PARENS: ::core::ffi::c_int = NESTED_INT * (LITERAL_CHAR + true_0); pub const PTR_ARITHMETIC: *const ::core::ffi::c_char = unsafe { LITERAL_STR @@ -66,7 +71,24 @@ pub const PTR_ARITHMETIC: *const ::core::ffi::c_char = unsafe { .offset(-(3 as ::core::ffi::c_int as isize)) }; pub const WIDENING_CAST: ::core::ffi::c_ulonglong = LITERAL_INT as ::core::ffi::c_ulonglong; +pub const NARROWING_CAST: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; pub const CONVERSION_CAST: ::core::ffi::c_double = LITERAL_INT as ::core::ffi::c_double; +pub const INDEXING: ::core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; +pub const STR_CONCATENATION: [::core::ffi::c_char; 18] = unsafe { + ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") +}; +pub const REF_MACRO: *const ::core::ffi::c_char = unsafe { + NESTED_STR + .as_ptr() + .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) as *const ::core::ffi::c_char +}; +pub const REF_LITERAL: *mut S = &LITERAL_STRUCT as *const S as *mut S; +pub const TERNARY: ::core::ffi::c_int = if LITERAL_BOOL != 0 { + 1 as ::core::ffi::c_int +} else { + 2 as ::core::ffi::c_int +}; +pub const MEMBER: ::core::ffi::c_int = LITERAL_STRUCT.i; #[no_mangle] pub unsafe extern "C" fn local_muts() { let mut literal_int: ::core::ffi::c_int = LITERAL_INT; @@ -85,45 +107,28 @@ pub unsafe extern "C" fn local_muts() { let mut nested_str: [::core::ffi::c_char; 6] = NESTED_STR; let mut nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; let mut nested_struct: S = NESTED_STRUCT; - let mut negative_int: ::core::ffi::c_int = -LITERAL_INT; - let mut int_arithmetic: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; - let mut mixed_arithmetic: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut negative_int: ::core::ffi::c_int = NEGATIVE_INT; + let mut int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; + let mut mixed_arithmetic: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut parens: ::core::ffi::c_int = PARENS; let mut ptr_arithmetic: *const ::core::ffi::c_char = PTR_ARITHMETIC; let mut widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; - let mut narrowing_cast: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; + let mut narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; let mut conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; - let mut indexing: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; - 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 indexing: ::core::ffi::c_char = INDEXING; + let mut str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr(); + let mut str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; 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 - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - 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 - } else { - 2 as ::core::ffi::c_int - }; - let mut member: ::core::ffi::c_int = LITERAL_STRUCT.i; + let mut ref_indexing: *const ::core::ffi::c_char = REF_MACRO; + let mut ref_struct: *const S = REF_LITERAL; + let mut ternary: ::core::ffi::c_int = TERNARY; + let mut member: ::core::ffi::c_int = MEMBER; let mut stmt_expr: ::core::ffi::c_float = ({ let mut builtin_0: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let mut indexing_0: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut mixed: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut indexing_0: ::core::ffi::c_char = INDEXING; + let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int; while i < builtin_0 { mixed += indexing_0 as ::core::ffi::c_float; @@ -150,43 +155,27 @@ pub unsafe extern "C" fn local_consts() { let nested_str: [::core::ffi::c_char; 6] = NESTED_STR; let nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; let nested_struct: S = NESTED_STRUCT; - let negative_int: ::core::ffi::c_int = -LITERAL_INT; - let int_arithmetic: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; - let mixed_arithmetic: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let negative_int: ::core::ffi::c_int = NEGATIVE_INT; + let int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; + let mixed_arithmetic: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let parens: ::core::ffi::c_int = PARENS; let ptr_arithmetic: *const ::core::ffi::c_char = PTR_ARITHMETIC; let widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; - let narrowing_cast: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; + let narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; let conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; - let indexing: ::core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; - let str_concatenation: [::core::ffi::c_char; 18] = - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0"); + let indexing: ::core::ffi::c_char = INDEXING; + let str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr(); + let str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; 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 - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - 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 - } else { - 2 as ::core::ffi::c_int - }; - let member: ::core::ffi::c_int = LITERAL_STRUCT.i; + let ref_indexing: *const ::core::ffi::c_char = REF_MACRO; + let ref_struct: *const S = REF_LITERAL; + let ternary: ::core::ffi::c_int = TERNARY; + let member: ::core::ffi::c_int = MEMBER; let stmt_expr: ::core::ffi::c_float = ({ let mut builtin_0: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let mut indexing_0: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut mixed: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut indexing_0: ::core::ffi::c_char = INDEXING; + let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int; while i < builtin_0 { mixed += indexing_0 as ::core::ffi::c_float; @@ -215,30 +204,25 @@ static mut global_static_const_nested_str_ptr: *const ::core::ffi::c_char = NEST static mut global_static_const_nested_str: [::core::ffi::c_char; 6] = NESTED_STR; static mut global_static_const_nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; static mut global_static_const_nested_struct: S = NESTED_STRUCT; -static mut global_static_const_negative_int: ::core::ffi::c_int = -LITERAL_INT; -static mut global_static_const_int_arithmetic: ::core::ffi::c_int = - NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +static mut global_static_const_negative_int: ::core::ffi::c_int = NEGATIVE_INT; +static mut global_static_const_int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; static mut global_static_const_mixed_arithmetic: ::core::ffi::c_float = - (LITERAL_INT as ::core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) as ::core::ffi::c_float; + MIXED_ARITHMETIC as ::core::ffi::c_float; static mut global_static_const_parens: ::core::ffi::c_int = PARENS; static mut global_static_const_ptr_arithmetic: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); static mut global_static_const_widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; -static mut global_static_const_narrowing_cast: ::core::ffi::c_char = - LITERAL_INT as ::core::ffi::c_char; +static mut global_static_const_narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; static mut global_static_const_conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; static mut global_static_const_indexing: ::core::ffi::c_char = 0; static mut global_static_const_str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; -static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = unsafe { - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") -}; + STR_CONCATENATION.as_ptr(); +static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; static mut global_static_const_builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; static mut global_static_const_ref_indexing: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); -static mut global_static_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S; +static mut global_static_const_ref_struct: *const S = REF_LITERAL; static mut global_static_const_ternary: ::core::ffi::c_int = 0; static mut global_static_const_member: ::core::ffi::c_int = 0; #[no_mangle] @@ -278,14 +262,12 @@ pub static mut global_const_nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY #[no_mangle] pub static mut global_const_nested_struct: S = NESTED_STRUCT; #[no_mangle] -pub static mut global_const_negative_int: ::core::ffi::c_int = -LITERAL_INT; +pub static mut global_const_negative_int: ::core::ffi::c_int = NEGATIVE_INT; #[no_mangle] -pub static mut global_const_int_arithmetic: ::core::ffi::c_int = - NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +pub static mut global_const_int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; #[no_mangle] pub static mut global_const_mixed_arithmetic: ::core::ffi::c_float = - (LITERAL_INT as ::core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) as ::core::ffi::c_float; + MIXED_ARITHMETIC as ::core::ffi::c_float; #[no_mangle] pub static mut global_const_parens: ::core::ffi::c_int = PARENS; #[no_mangle] @@ -294,19 +276,16 @@ pub static mut global_const_ptr_arithmetic: *const ::core::ffi::c_char = #[no_mangle] pub static mut global_const_widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; #[no_mangle] -pub static mut global_const_narrowing_cast: ::core::ffi::c_char = - LITERAL_INT as ::core::ffi::c_char; +pub static mut global_const_narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; #[no_mangle] pub static mut global_const_conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; #[no_mangle] pub static mut global_const_indexing: ::core::ffi::c_char = 0; #[no_mangle] pub static mut global_const_str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; + STR_CONCATENATION.as_ptr(); #[no_mangle] -pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = unsafe { - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") -}; +pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; #[no_mangle] pub static mut global_const_builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; @@ -314,7 +293,7 @@ pub static mut global_const_builtin: ::core::ffi::c_int = pub static mut global_const_ref_indexing: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); #[no_mangle] -pub static mut global_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S; +pub static mut global_const_ref_struct: *const S = REF_LITERAL; #[no_mangle] pub static mut global_const_ternary: ::core::ffi::c_int = 0; #[no_mangle] @@ -420,29 +399,15 @@ pub unsafe extern "C" fn late_init_var() -> ::core::ffi::c_int { } unsafe extern "C" fn c2rust_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 - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - global_static_const_ternary = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - global_static_const_member = LITERAL_STRUCT.i; + global_static_const_indexing = INDEXING; + global_static_const_ref_indexing = REF_MACRO; + global_static_const_ternary = TERNARY; + global_static_const_member = MEMBER; 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 - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - global_const_ternary = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - global_const_member = LITERAL_STRUCT.i; + global_const_indexing = INDEXING; + global_const_ref_indexing = REF_MACRO; + global_const_ternary = TERNARY; + global_const_member = MEMBER; } #[used] #[cfg_attr(target_os = "linux", link_section = ".init_array")] diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap index 1541727a10..2cb96b462c 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap @@ -58,6 +58,11 @@ pub const NESTED_CHAR: ::core::ffi::c_int = LITERAL_CHAR; pub const NESTED_STR: [::core::ffi::c_char; 6] = LITERAL_STR; pub const NESTED_ARRAY: [::core::ffi::c_int; 3] = LITERAL_ARRAY; pub const NESTED_STRUCT: S = LITERAL_STRUCT; +pub const NEGATIVE_INT: ::core::ffi::c_int = -LITERAL_INT; +pub const INT_ARITHMETIC: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +pub const MIXED_ARITHMETIC: ::core::ffi::c_double = LITERAL_INT as ::core::ffi::c_double + + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double + - true_0 as ::core::ffi::c_double; pub const PARENS: ::core::ffi::c_int = NESTED_INT * (LITERAL_CHAR + true_0); pub const PTR_ARITHMETIC: *const ::core::ffi::c_char = unsafe { LITERAL_STR @@ -66,7 +71,24 @@ pub const PTR_ARITHMETIC: *const ::core::ffi::c_char = unsafe { .offset(-(3 as ::core::ffi::c_int as isize)) }; pub const WIDENING_CAST: ::core::ffi::c_ulonglong = LITERAL_INT as ::core::ffi::c_ulonglong; +pub const NARROWING_CAST: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; pub const CONVERSION_CAST: ::core::ffi::c_double = LITERAL_INT as ::core::ffi::c_double; +pub const INDEXING: ::core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; +pub const STR_CONCATENATION: [::core::ffi::c_char; 18] = unsafe { + ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") +}; +pub const REF_MACRO: *const ::core::ffi::c_char = unsafe { + NESTED_STR + .as_ptr() + .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) as *const ::core::ffi::c_char +}; +pub const REF_LITERAL: *mut S = &LITERAL_STRUCT as *const S as *mut S; +pub const TERNARY: ::core::ffi::c_int = if LITERAL_BOOL != 0 { + 1 as ::core::ffi::c_int +} else { + 2 as ::core::ffi::c_int +}; +pub const MEMBER: ::core::ffi::c_int = LITERAL_STRUCT.i; #[unsafe(no_mangle)] pub unsafe extern "C" fn local_muts() { let mut literal_int: ::core::ffi::c_int = LITERAL_INT; @@ -85,45 +107,28 @@ pub unsafe extern "C" fn local_muts() { let mut nested_str: [::core::ffi::c_char; 6] = NESTED_STR; let mut nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; let mut nested_struct: S = NESTED_STRUCT; - let mut negative_int: ::core::ffi::c_int = -LITERAL_INT; - let mut int_arithmetic: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; - let mut mixed_arithmetic: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut negative_int: ::core::ffi::c_int = NEGATIVE_INT; + let mut int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; + let mut mixed_arithmetic: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut parens: ::core::ffi::c_int = PARENS; let mut ptr_arithmetic: *const ::core::ffi::c_char = PTR_ARITHMETIC; let mut widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; - let mut narrowing_cast: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; + let mut narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; let mut conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; - let mut indexing: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; - 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 indexing: ::core::ffi::c_char = INDEXING; + let mut str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr(); + let mut str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; 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 - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - 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 - } else { - 2 as ::core::ffi::c_int - }; - let mut member: ::core::ffi::c_int = LITERAL_STRUCT.i; + let mut ref_indexing: *const ::core::ffi::c_char = REF_MACRO; + let mut ref_struct: *const S = REF_LITERAL; + let mut ternary: ::core::ffi::c_int = TERNARY; + let mut member: ::core::ffi::c_int = MEMBER; let mut stmt_expr: ::core::ffi::c_float = ({ let mut builtin_0: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let mut indexing_0: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut mixed: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut indexing_0: ::core::ffi::c_char = INDEXING; + let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int; while i < builtin_0 { mixed += indexing_0 as ::core::ffi::c_float; @@ -150,43 +155,27 @@ pub unsafe extern "C" fn local_consts() { let nested_str: [::core::ffi::c_char; 6] = NESTED_STR; let nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; let nested_struct: S = NESTED_STRUCT; - let negative_int: ::core::ffi::c_int = -LITERAL_INT; - let int_arithmetic: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; - let mixed_arithmetic: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let negative_int: ::core::ffi::c_int = NEGATIVE_INT; + let int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; + let mixed_arithmetic: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let parens: ::core::ffi::c_int = PARENS; let ptr_arithmetic: *const ::core::ffi::c_char = PTR_ARITHMETIC; let widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; - let narrowing_cast: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; + let narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; let conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; - let indexing: ::core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; - let str_concatenation: [::core::ffi::c_char; 18] = - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0"); + let indexing: ::core::ffi::c_char = INDEXING; + let str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr(); + let str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; 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 - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - 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 - } else { - 2 as ::core::ffi::c_int - }; - let member: ::core::ffi::c_int = LITERAL_STRUCT.i; + let ref_indexing: *const ::core::ffi::c_char = REF_MACRO; + let ref_struct: *const S = REF_LITERAL; + let ternary: ::core::ffi::c_int = TERNARY; + let member: ::core::ffi::c_int = MEMBER; let stmt_expr: ::core::ffi::c_float = ({ let mut builtin_0: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let mut indexing_0: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut mixed: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut indexing_0: ::core::ffi::c_char = INDEXING; + let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int; while i < builtin_0 { mixed += indexing_0 as ::core::ffi::c_float; @@ -215,30 +204,25 @@ static mut global_static_const_nested_str_ptr: *const ::core::ffi::c_char = NEST static mut global_static_const_nested_str: [::core::ffi::c_char; 6] = NESTED_STR; static mut global_static_const_nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; static mut global_static_const_nested_struct: S = NESTED_STRUCT; -static mut global_static_const_negative_int: ::core::ffi::c_int = -LITERAL_INT; -static mut global_static_const_int_arithmetic: ::core::ffi::c_int = - NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +static mut global_static_const_negative_int: ::core::ffi::c_int = NEGATIVE_INT; +static mut global_static_const_int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; static mut global_static_const_mixed_arithmetic: ::core::ffi::c_float = - (LITERAL_INT as ::core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) as ::core::ffi::c_float; + MIXED_ARITHMETIC as ::core::ffi::c_float; static mut global_static_const_parens: ::core::ffi::c_int = PARENS; static mut global_static_const_ptr_arithmetic: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); static mut global_static_const_widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; -static mut global_static_const_narrowing_cast: ::core::ffi::c_char = - LITERAL_INT as ::core::ffi::c_char; +static mut global_static_const_narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; static mut global_static_const_conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; static mut global_static_const_indexing: ::core::ffi::c_char = 0; static mut global_static_const_str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; -static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = unsafe { - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") -}; + STR_CONCATENATION.as_ptr(); +static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; static mut global_static_const_builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; static mut global_static_const_ref_indexing: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); -static mut global_static_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S; +static mut global_static_const_ref_struct: *const S = REF_LITERAL; static mut global_static_const_ternary: ::core::ffi::c_int = 0; static mut global_static_const_member: ::core::ffi::c_int = 0; #[unsafe(no_mangle)] @@ -278,14 +262,12 @@ pub static mut global_const_nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY #[unsafe(no_mangle)] pub static mut global_const_nested_struct: S = NESTED_STRUCT; #[unsafe(no_mangle)] -pub static mut global_const_negative_int: ::core::ffi::c_int = -LITERAL_INT; +pub static mut global_const_negative_int: ::core::ffi::c_int = NEGATIVE_INT; #[unsafe(no_mangle)] -pub static mut global_const_int_arithmetic: ::core::ffi::c_int = - NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +pub static mut global_const_int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; #[unsafe(no_mangle)] pub static mut global_const_mixed_arithmetic: ::core::ffi::c_float = - (LITERAL_INT as ::core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) as ::core::ffi::c_float; + MIXED_ARITHMETIC as ::core::ffi::c_float; #[unsafe(no_mangle)] pub static mut global_const_parens: ::core::ffi::c_int = PARENS; #[unsafe(no_mangle)] @@ -294,19 +276,16 @@ pub static mut global_const_ptr_arithmetic: *const ::core::ffi::c_char = #[unsafe(no_mangle)] pub static mut global_const_widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; #[unsafe(no_mangle)] -pub static mut global_const_narrowing_cast: ::core::ffi::c_char = - LITERAL_INT as ::core::ffi::c_char; +pub static mut global_const_narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; #[unsafe(no_mangle)] pub static mut global_const_conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; #[unsafe(no_mangle)] pub static mut global_const_indexing: ::core::ffi::c_char = 0; #[unsafe(no_mangle)] pub static mut global_const_str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; + STR_CONCATENATION.as_ptr(); #[unsafe(no_mangle)] -pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = unsafe { - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") -}; +pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; #[unsafe(no_mangle)] pub static mut global_const_builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; @@ -314,7 +293,7 @@ pub static mut global_const_builtin: ::core::ffi::c_int = pub static mut global_const_ref_indexing: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); #[unsafe(no_mangle)] -pub static mut global_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S; +pub static mut global_const_ref_struct: *const S = REF_LITERAL; #[unsafe(no_mangle)] pub static mut global_const_ternary: ::core::ffi::c_int = 0; #[unsafe(no_mangle)] @@ -420,29 +399,15 @@ pub unsafe extern "C" fn late_init_var() -> ::core::ffi::c_int { } unsafe extern "C" fn c2rust_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 - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - global_static_const_ternary = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - global_static_const_member = LITERAL_STRUCT.i; + global_static_const_indexing = INDEXING; + global_static_const_ref_indexing = REF_MACRO; + global_static_const_ternary = TERNARY; + global_static_const_member = MEMBER; 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 - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - global_const_ternary = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - global_const_member = LITERAL_STRUCT.i; + global_const_indexing = INDEXING; + global_const_ref_indexing = REF_MACRO; + global_const_ternary = TERNARY; + global_const_member = MEMBER; } #[used] #[cfg_attr(target_os = "linux", unsafe(link_section = ".init_array"))] diff --git a/tests/unit/pointers/src/test_pointers.rs b/tests/unit/pointers/src/test_pointers.rs index 6a95f04988..beb74e85c6 100644 --- a/tests/unit/pointers/src/test_pointers.rs +++ b/tests/unit/pointers/src/test_pointers.rs @@ -1,4 +1,4 @@ -//! feature_c_variadic, feature_raw_ref_op +//! feature_c_variadic, feature_raw_ref_op, feature_strict_provenance use crate::function_pointers::rust_entry3; use crate::pointer_arith::rust_entry2; diff --git a/tests/unit/statics/src/test_sections.rs b/tests/unit/statics/src/test_sections.rs index 964183f83e..f4516fe32f 100644 --- a/tests/unit/statics/src/test_sections.rs +++ b/tests/unit/statics/src/test_sections.rs @@ -1,4 +1,4 @@ -//! feature_raw_ref_op +//! feature_raw_ref_op, feature_strict_provenance #[cfg(not(target_os = "macos"))] use crate::attributes::{rust_no_attrs, rust_used_static, rust_used_static2, rust_used_static3};