Skip to content

transpile: Fix translation failures exposed by SQLite - #2001

Open
thedataking wants to merge 5 commits into
masterfrom
perl/sqlite-transpiler-fixes
Open

transpile: Fix translation failures exposed by SQLite#2001
thedataking wants to merge 5 commits into
masterfrom
perl/sqlite-transpiler-fixes

Conversation

@thedataking

@thedataking thedataking commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Fix five translation failures exposed by SQLite's individual source files:

  • Register the main file before emitting the exporter's file table. Comment-only translation units otherwise introduce an unknown file ID and panic during include-path lookup.
  • Construct integer-derived opaque pointers through byte pointers. Exposed-provenance constructors require sized pointees, while opaque extern types are unsized.
  • Specify the destination type when reading function pointers with va_arg. Enclosing casts can prevent Rust from inferring it.
  • Lower atomic function pointer operations through raw pointers. Rust's atomic intrinsics reject the Option<fn> representation of nullable C callbacks.
  • Initialize _Atomic storage through its underlying value type. Default initialization otherwise fails for local atomic declarations, including explicitly initialized ones.

@thedataking
thedataking force-pushed the perl/sqlite-transpiler-fixes branch from f409fa9 to c6c1988 Compare September 8, 2026 02:33
@thedataking
thedataking marked this pull request as ready for review September 8, 2026 03:24
@thedataking
thedataking requested a review from ahomescu September 8, 2026 03:25
Translation units without declarations have no AST nodes to register
their main file. Exporting comments then introduces a file ID absent
from the file table, causing include-path lookup to panic.

Register the main file before serializing the table so comments always
refer to an exported file.
…nters

Exposed-provenance constructors require Sized pointees, but forward
declarations become unsized extern types. Construct a byte pointer
first, then cast to the opaque pointer type while preserving its
constness. This allows integer sentinel values and runtime addresses
to initialize opaque pointers in both supported Rust editions.
… va_arg

An enclosing cast can prevent Rust from inferring the destination of
the transmute used for nullable function pointers. Pass the converted
C type explicitly so va_arg results can be assigned through function
pointer typedefs and struct fields.
Rust atomic intrinsics reject Option<fn>, the representation of nullable
C function pointers. Convert atomic operands to raw pointers and
convert results back to their function pointer type.

Apply this to loads, stores, exchanges, and compare-exchanges, including
the expected value written back after a failed comparison. Null
callbacks retain their null representation.
Default initialization does not handle CTypeKind::Atomic, so local
_Atomic declarations fail to translate even when they have an explicit
initializer. Delegate to the underlying value type to produce the
initializer for the atomic storage.
@thedataking
thedataking force-pushed the perl/sqlite-transpiler-fixes branch from c6c1988 to 2ec4c4d Compare September 8, 2026 03:34
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn sentinel() -> *mut Opaque {
return ::core::ptr::with_exposed_provenance_mut::<u8>(8 as ::core::ffi::c_int as usize)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there isn't a matching call to expose_provenance, this is undefined behavior.

.ast_context
.is_forward_declared_type(pointee_type_id.ctype);
let pointee_type_rs = if is_opaque {
mk().path_ty(vec!["u8"])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure yet if this should be u8 or c_void.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use c_void in other places, so yeah we should keep it consistent.

transmute_expr(mk().infer_ty(), mk().infer_ty(), val)
VaArgCastKind::Transmute(ty) => {
// An enclosing cast or field access may prevent
// inference of the transmute's destination type.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could either this comment or the current commit message provide an example of the generated code?

.transpose()?;
let weak = weak_id.and_then(|x| self.convert_constant_bool(x));

// Rust represents nullable C function pointers as Option<fn>, which

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only covers the AST atomics, but not any of the __sync_* or __atomic_* builtins. You could refactor this to cover everything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants