From 8b47edce66ba4bbac6903f7650da11ffab66800c Mon Sep 17 00:00:00 2001 From: Khyber Sen Date: Thu, 2 Oct 2025 02:04:49 -0700 Subject: [PATCH] transpile: const macros: skip fn ptr types, as they don't work with portable types The workaround for non-portable types for const macros is to insert a use-site cast to the portable type, but this works differently for fn ptrs, so while #1321 is fixed, just skip fn ptr const macros. This should get #1384 to pass CI by working around this issue there, and it should also workaround #1366, although #1366 in `libxml2` appears to have been fixed/worked around from some other change, as #1385 now passes CI. --- c2rust-transpile/src/translator/mod.rs | 8 ++++++++ c2rust-transpile/tests/snapshots/os-specific/macros.c | 11 ++++++++++- .../snapshots__transpile-linux@macros.c.snap | 5 +++++ .../snapshots__transpile-macos@macros.c.snap | 5 +++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index dd9dc99434..c2a9fe1171 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -2173,6 +2173,14 @@ impl<'c> Translation<'c> { // Join ty and cur_ty to the smaller of the two types. If the // types are not cast-compatible, abort the fold. let ty_kind = self.ast_context.resolve_type(ty).kind.clone(); + if matches!(ty_kind, CTypeKind::Function(..)) { + // TODO This is a temporary workaround for #1321 (portable types in const macros). + // The workaround for most types is to create a const macro with non-portable type + // and insert casts at use sites, but this doesn't work the same for fn ptr types. + // So don't translate fn ptr const macros yet until #1321 is fixed. + return Err(format_err!("fn ptr const macros not yet supported due to non-portable types; see #1321")); + } + if let Some((canon_val, canon_ty)) = canonical { let canon_ty_kind = self.ast_context.resolve_type(canon_ty).kind.clone(); if let Some(smaller_ty) = diff --git a/c2rust-transpile/tests/snapshots/os-specific/macros.c b/c2rust-transpile/tests/snapshots/os-specific/macros.c index eb29193550..7dd6130980 100644 --- a/c2rust-transpile/tests/snapshots/os-specific/macros.c +++ b/c2rust-transpile/tests/snapshots/os-specific/macros.c @@ -19,7 +19,7 @@ int size_of_dynamic(int n) { } #endif -// From Lua's `lobject.c`. +// From `lua`'s `lobject.c`. #define POS "\"]" /* number of chars of a literal string without the ending \0 */ @@ -28,3 +28,12 @@ int size_of_dynamic(int n) { void memcpy_str_literal(char *out) { memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); } + +// From `python2`'s `bytes_methods.c`. + +#define Py_MEMCPY memcpy + +void f(void *x) { + size_t len = 0; + Py_MEMCPY(x, x, len); +} diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-linux@macros.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-linux@macros.c.snap index 285723e3f7..e3bc782714 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile-linux@macros.c.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile-linux@macros.c.snap @@ -44,3 +44,8 @@ pub unsafe extern "C" fn memcpy_str_literal(mut out: *mut core::ffi::c_char) { .wrapping_mul(::core::mem::size_of::() as size_t), ); } +#[no_mangle] +pub unsafe extern "C" fn f(mut x: *mut core::ffi::c_void) { + let mut len: size_t = 0 as size_t; + memcpy(x, x, len); +} diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-macos@macros.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-macos@macros.c.snap index e6838124c4..6e153a1e7c 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile-macos@macros.c.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile-macos@macros.c.snap @@ -45,3 +45,8 @@ pub unsafe extern "C" fn memcpy_str_literal(mut out: *mut core::ffi::c_char) { .wrapping_mul(::core::mem::size_of::() as size_t), ); } +#[no_mangle] +pub unsafe extern "C" fn f(mut x: *mut core::ffi::c_void) { + let mut len: size_t = 0 as size_t; + memcpy(x, x, len); +}