From 86495dcfe794daece697af9eef434afb2214f1ba Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sun, 10 May 2026 13:54:57 +0100 Subject: [PATCH 1/4] Use default literals instead of Default::default() in const initialization --- cpp2rust/converter/converter.cpp | 30 +++++++++++++++++++++++------- cpp2rust/converter/converter.h | 20 ++++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 67e8e705..e9cf7b92 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -445,6 +445,8 @@ void Converter::ConvertVarDecl(clang::VarDecl *decl) { return; } auto qual_type = decl->getType(); + PushConstInitializer static_init(*this, decl->isFileVarDecl() || + decl->isStaticLocal()); if (decl->hasInit()) { StrCat(token::kAssign); ConvertVarInit(qual_type, decl->getInit()); @@ -3043,6 +3045,18 @@ std::string Converter::GetDefaultAsStringFallback(clang::QualType qual_type) { return std::format("0.0_{}", ToString(qual_type)); } + if (auto record = qual_type->getAsRecordDecl(); + record && in_const_initializer_) { + if (auto cxx = clang::dyn_cast(record)) { + assert(GetUserDefinedDefaultConstructor(cxx) == nullptr && + "Default initializing globals using default constructor is not " + "supported"); + } + Buffer buf(*this); + EmitDefaultStructLiteral(record); + return std::move(buf).str(); + } + return std::format("<{}>::default()", ToString(qual_type)); } @@ -3458,13 +3472,15 @@ void Converter::AddDefaultTrait(const clang::RecordDecl *decl) { } } - StrCat(struct_name); - { - PushBrace struct_brace(*this); - for (auto *field : decl->fields()) { - StrCat(GetNamedDeclAsString(field), token::kColon, - GetDefaultAsString(field->getType()), token::kComma); - } + EmitDefaultStructLiteral(decl); +} + +void Converter::EmitDefaultStructLiteral(const clang::RecordDecl *decl) { + StrCat(GetRecordName(decl)); + PushBrace brace(*this); + for (auto *field : decl->fields()) { + StrCat(GetNamedDeclAsString(field), token::kColon, + GetDefaultAsString(field->getType()), token::kComma); } } diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index b24d5982..217d09f6 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -464,6 +464,8 @@ class Converter : public clang::RecursiveASTVisitor { virtual void AddDefaultTraitForUnion(const clang::RecordDecl *decl); + void EmitDefaultStructLiteral(const clang::RecordDecl *decl); + virtual void AddByteReprTrait(const clang::RecordDecl *decl); virtual void @@ -517,6 +519,7 @@ class Converter : public clang::RecursiveASTVisitor { clang::ASTContext &ctx_; clang::FunctionDecl *curr_function_ = nullptr; bool in_function_formals_ = false; + bool in_const_initializer_ = false; std::optional autoref_mut_; struct PushExplicitAutoref { @@ -528,6 +531,23 @@ class Converter : public clang::RecursiveASTVisitor { } ~PushExplicitAutoref() { c.autoref_mut_ = prev; } }; + + struct PushConstInitializer { + Converter &c; + bool prev; + bool enabled; + PushConstInitializer(Converter &c, bool enabled) + : c(c), prev(c.in_const_initializer_), enabled(enabled) { + if (enabled) { + c.in_const_initializer_ = true; + } + } + ~PushConstInitializer() { + if (enabled) { + c.in_const_initializer_ = prev; + } + } + }; std::stack curr_for_inc_; std::stack curr_init_type_; From c2336d9001dbc60cb43f772618595cd455abd7c6 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sun, 10 May 2026 13:55:17 +0100 Subject: [PATCH 2/4] Add default_in_statics test --- tests/unit/default_in_statics.cpp | 82 ++++++ tests/unit/out/refcount/default_in_statics.rs | 243 ++++++++++++++++++ tests/unit/out/unsafe/default_in_statics.rs | 173 +++++++++++++ 3 files changed, 498 insertions(+) create mode 100644 tests/unit/default_in_statics.cpp create mode 100644 tests/unit/out/refcount/default_in_statics.rs create mode 100644 tests/unit/out/unsafe/default_in_statics.rs diff --git a/tests/unit/default_in_statics.cpp b/tests/unit/default_in_statics.cpp new file mode 100644 index 00000000..466c6bdf --- /dev/null +++ b/tests/unit/default_in_statics.cpp @@ -0,0 +1,82 @@ +#include +#include + +typedef int (*FnPtr)(int); + +struct Inner { + int v; + const char *name; +}; + +struct Outer { + int *p1; + const int *p2; + int *arr[3]; + const char *cp; + int **pp; + Inner inner; + int x; + FnPtr fn; +}; + +struct Foo { + const char *s1; + const char *s2; + FnPtr fn1; + FnPtr fn2; + int n; +}; + +static FnPtr static_fn; +static Outer static_outer; +static Inner static_inner_array[2]; + +static Foo static_foo = {"hello", 0, 0, 0, 42}; + +static Foo static_foo_array[2] = { + {"first", 0, 0, 0, 1}, + {"second", 0, 0, 0, 2}, +}; + +void check_local_static() { + static Outer local_outer; + static FnPtr local_fn; + static int *local_p; + assert(local_outer.p1 == nullptr); + assert(local_outer.fn == nullptr); + assert(local_fn == nullptr); + assert(local_p == nullptr); +} + +int main() { + assert(static_fn == nullptr); + + assert(static_outer.p1 == nullptr); + assert(static_outer.p2 == nullptr); + assert(static_outer.cp == nullptr); + assert(static_outer.pp == nullptr); + assert(static_outer.fn == nullptr); + for (int i = 0; i < 3; ++i) { + assert(static_outer.arr[i] == nullptr); + } + assert(static_outer.inner.name == nullptr); + + for (int i = 0; i < 2; ++i) { + assert(static_inner_array[i].name == nullptr); + } + + assert(static_foo.s2 == nullptr); + assert(static_foo.fn1 == nullptr); + assert(static_foo.fn2 == nullptr); + assert(static_foo.n == 42); + + for (int i = 0; i < 2; ++i) { + assert(static_foo_array[i].s2 == nullptr); + assert(static_foo_array[i].fn1 == nullptr); + assert(static_foo_array[i].fn2 == nullptr); + } + + check_local_static(); + + return 0; +} diff --git a/tests/unit/out/refcount/default_in_statics.rs b/tests/unit/out/refcount/default_in_statics.rs new file mode 100644 index 00000000..a51d0029 --- /dev/null +++ b/tests/unit/out/refcount/default_in_statics.rs @@ -0,0 +1,243 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Default)] +pub struct Inner { + pub v: Value, + pub name: Value>, +} +impl Clone for Inner { + fn clone(&self) -> Self { + let mut this = Self { + v: Rc::new(RefCell::new((*self.v.borrow()))), + name: Rc::new(RefCell::new((*self.name.borrow()).clone())), + }; + this + } +} +impl ByteRepr for Inner {} +#[derive()] +pub struct Outer { + pub p1: Value>, + pub p2: Value>, + pub arr: Value]>>, + pub cp: Value>, + pub pp: Value>>, + pub inner: Value, + pub x: Value, + pub fn_: Value i32>>, +} +impl Clone for Outer { + fn clone(&self) -> Self { + let mut this = Self { + p1: Rc::new(RefCell::new((*self.p1.borrow()).clone())), + p2: Rc::new(RefCell::new((*self.p2.borrow()).clone())), + arr: Rc::new(RefCell::new((*self.arr.borrow()).clone())), + cp: Rc::new(RefCell::new((*self.cp.borrow()).clone())), + pp: Rc::new(RefCell::new((*self.pp.borrow()).clone())), + inner: Rc::new(RefCell::new((*self.inner.borrow()).clone())), + x: Rc::new(RefCell::new((*self.x.borrow()))), + fn_: Rc::new(RefCell::new((*self.fn_.borrow()).clone())), + }; + this + } +} +impl Default for Outer { + fn default() -> Self { + Outer { + p1: Rc::new(RefCell::new(Ptr::::null())), + p2: Rc::new(RefCell::new(Ptr::::null())), + arr: Rc::new(RefCell::new( + (0..3) + .map(|_| Ptr::::null()) + .collect::]>>(), + )), + cp: Rc::new(RefCell::new(Ptr::::null())), + pp: Rc::new(RefCell::new(Ptr::>::null())), + inner: >::default(), + x: >::default(), + fn_: Rc::new(RefCell::new(FnPtr::null())), + } + } +} +impl ByteRepr for Outer {} +#[derive()] +pub struct Foo { + pub s1: Value>, + pub s2: Value>, + pub fn1: Value i32>>, + pub fn2: Value i32>>, + pub n: Value, +} +impl Clone for Foo { + fn clone(&self) -> Self { + let mut this = Self { + s1: Rc::new(RefCell::new((*self.s1.borrow()).clone())), + s2: Rc::new(RefCell::new((*self.s2.borrow()).clone())), + fn1: Rc::new(RefCell::new((*self.fn1.borrow()).clone())), + fn2: Rc::new(RefCell::new((*self.fn2.borrow()).clone())), + n: Rc::new(RefCell::new((*self.n.borrow()))), + }; + this + } +} +impl Default for Foo { + fn default() -> Self { + Foo { + s1: Rc::new(RefCell::new(Ptr::::null())), + s2: Rc::new(RefCell::new(Ptr::::null())), + fn1: Rc::new(RefCell::new(FnPtr::null())), + fn2: Rc::new(RefCell::new(FnPtr::null())), + n: >::default(), + } + } +} +impl ByteRepr for Foo {} +thread_local!( + pub static static_p1: Value> = Rc::new(RefCell::new(Ptr::::null())); +); +thread_local!( + pub static static_p2: Value> = Rc::new(RefCell::new(Ptr::::null())); +); +thread_local!( + pub static static_cp: Value> = Rc::new(RefCell::new(Ptr::::null())); +); +thread_local!( + pub static static_arr: Value]>> = Rc::new(RefCell::new( + (0..4) + .map(|_| Ptr::::null()) + .collect::]>>(), + )); +); +thread_local!( + pub static static_pp: Value>> = Rc::new(RefCell::new(Ptr::>::null())); +); +thread_local!( + pub static static_fn: Value i32>> = Rc::new(RefCell::new(FnPtr::null())); +); +thread_local!( + pub static static_outer: Value = Rc::new(RefCell::new(::default())); +); +thread_local!( + pub static static_inner_array: Value> = Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )); +); +thread_local!( + pub static static_foo: Value = Rc::new(RefCell::new(Foo { + s1: Rc::new(RefCell::new(Ptr::from_string_literal("hello"))), + s2: Rc::new(RefCell::new(Default::default())), + fn1: Rc::new(RefCell::new(FnPtr::null())), + fn2: Rc::new(RefCell::new(FnPtr::null())), + n: Rc::new(RefCell::new(42)), + })); +); +thread_local!( + pub static static_foo_array: Value> = Rc::new(RefCell::new(Box::new([ + Foo { + s1: Rc::new(RefCell::new(Ptr::from_string_literal("first"))), + s2: Rc::new(RefCell::new(Default::default())), + fn1: Rc::new(RefCell::new(FnPtr::null())), + fn2: Rc::new(RefCell::new(FnPtr::null())), + n: Rc::new(RefCell::new(1)), + }, + Foo { + s1: Rc::new(RefCell::new(Ptr::from_string_literal("second"))), + s2: Rc::new(RefCell::new(Default::default())), + fn1: Rc::new(RefCell::new(FnPtr::null())), + fn2: Rc::new(RefCell::new(FnPtr::null())), + n: Rc::new(RefCell::new(2)), + }, + ]))); +); +pub fn check_local_static_0() { + thread_local!( + static local_outer: Value = Rc::new(RefCell::new(::default())); + ); + thread_local!( + static local_fn: Value i32>> = Rc::new(RefCell::new(FnPtr::null())); + ); + thread_local!( + static local_p: Value> = Rc::new(RefCell::new(Ptr::::null())); + ); + assert!((*(*local_outer.with(Value::clone).borrow()).p1.borrow()).is_null()); + assert!((*(*local_outer.with(Value::clone).borrow()).fn_.borrow()).is_null()); + assert!((*local_fn.with(Value::clone).borrow()).is_null()); + assert!((*local_p.with(Value::clone).borrow()).is_null()); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + assert!((*static_p1.with(Value::clone).borrow()).is_null()); + assert!((*static_p2.with(Value::clone).borrow()).is_null()); + assert!((*static_cp.with(Value::clone).borrow()).is_null()); + let i: Value = Rc::new(RefCell::new(0)); + 'loop_: while ((*i.borrow()) < 4) { + assert!(((*static_arr.with(Value::clone).borrow())[(*i.borrow()) as usize]).is_null()); + (*i.borrow_mut()).prefix_inc(); + } + assert!((*static_pp.with(Value::clone).borrow()).is_null()); + assert!((*static_fn.with(Value::clone).borrow()).is_null()); + assert!((*(*static_outer.with(Value::clone).borrow()).p1.borrow()).is_null()); + assert!((*(*static_outer.with(Value::clone).borrow()).p2.borrow()).is_null()); + assert!((*(*static_outer.with(Value::clone).borrow()).cp.borrow()).is_null()); + assert!((*(*static_outer.with(Value::clone).borrow()).pp.borrow()).is_null()); + assert!((*(*static_outer.with(Value::clone).borrow()).fn_.borrow()).is_null()); + let i: Value = Rc::new(RefCell::new(0)); + 'loop_: while ((*i.borrow()) < 3) { + assert!(((*(*static_outer.with(Value::clone).borrow()).arr.borrow()) + [(*i.borrow()) as usize]) + .is_null()); + (*i.borrow_mut()).prefix_inc(); + } + assert!( + (*(*(*static_outer.with(Value::clone).borrow()).inner.borrow()) + .name + .borrow()) + .is_null() + ); + let i: Value = Rc::new(RefCell::new(0)); + 'loop_: while ((*i.borrow()) < 2) { + assert!( + (*(*static_inner_array.with(Value::clone).borrow())[(*i.borrow()) as usize] + .name + .borrow()) + .is_null() + ); + (*i.borrow_mut()).prefix_inc(); + } + assert!((*(*static_foo.with(Value::clone).borrow()).s2.borrow()).is_null()); + assert!((*(*static_foo.with(Value::clone).borrow()).fn1.borrow()).is_null()); + assert!((*(*static_foo.with(Value::clone).borrow()).fn2.borrow()).is_null()); + assert!(((*(*static_foo.with(Value::clone).borrow()).n.borrow()) == 42)); + let i: Value = Rc::new(RefCell::new(0)); + 'loop_: while ((*i.borrow()) < 2) { + assert!( + (*(*static_foo_array.with(Value::clone).borrow())[(*i.borrow()) as usize] + .s2 + .borrow()) + .is_null() + ); + assert!( + (*(*static_foo_array.with(Value::clone).borrow())[(*i.borrow()) as usize] + .fn1 + .borrow()) + .is_null() + ); + assert!( + (*(*static_foo_array.with(Value::clone).borrow())[(*i.borrow()) as usize] + .fn2 + .borrow()) + .is_null() + ); + (*i.borrow_mut()).prefix_inc(); + } + ({ check_local_static_0() }); + return 0; +} diff --git a/tests/unit/out/unsafe/default_in_statics.rs b/tests/unit/out/unsafe/default_in_statics.rs new file mode 100644 index 00000000..d2d96390 --- /dev/null +++ b/tests/unit/out/unsafe/default_in_statics.rs @@ -0,0 +1,173 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct Inner { + pub v: i32, + pub name: *const u8, +} +#[repr(C)] +#[derive(Clone)] +pub struct Outer { + pub p1: *mut i32, + pub p2: *const i32, + pub arr: [*mut i32; 3], + pub cp: *const u8, + pub pp: *mut *mut i32, + pub inner: Inner, + pub x: i32, + pub fn_: Option i32>, +} +impl Default for Outer { + fn default() -> Self { + Outer { + p1: std::ptr::null_mut(), + p2: std::ptr::null(), + arr: [std::ptr::null_mut(); 3], + cp: std::ptr::null(), + pp: std::ptr::null_mut(), + inner: ::default(), + x: 0_i32, + fn_: None, + } + } +} +#[repr(C)] +#[derive(Clone)] +pub struct Foo { + pub s1: *const u8, + pub s2: *const u8, + pub fn1: Option i32>, + pub fn2: Option i32>, + pub n: i32, +} +impl Default for Foo { + fn default() -> Self { + Foo { + s1: std::ptr::null(), + s2: std::ptr::null(), + fn1: None, + fn2: None, + n: 0_i32, + } + } +} +pub static mut static_p1: *mut i32 = std::ptr::null_mut(); +pub static mut static_p2: *const i32 = std::ptr::null(); +pub static mut static_cp: *const u8 = std::ptr::null(); +pub static mut static_arr: [*mut i32; 4] = [std::ptr::null_mut(); 4]; +pub static mut static_pp: *mut *mut i32 = std::ptr::null_mut(); +pub static mut static_fn: Option i32> = None; +pub static mut static_outer: Outer = Outer { + p1: std::ptr::null_mut(), + p2: std::ptr::null(), + arr: [std::ptr::null_mut(); 3], + cp: std::ptr::null(), + pp: std::ptr::null_mut(), + inner: Inner { + v: 0_i32, + name: std::ptr::null(), + }, + x: 0_i32, + fn_: None, +}; +pub static mut static_inner_array: [Inner; 2] = [Inner { + v: 0_i32, + name: std::ptr::null(), +}; 2]; +pub static mut static_foo: Foo = Foo { + s1: b"hello\0".as_ptr(), + s2: std::ptr::null(), + fn1: None, + fn2: None, + n: 42, +}; +pub static mut static_foo_array: [Foo; 2] = [ + Foo { + s1: b"first\0".as_ptr(), + s2: std::ptr::null(), + fn1: None, + fn2: None, + n: 1, + }, + Foo { + s1: b"second\0".as_ptr(), + s2: std::ptr::null(), + fn1: None, + fn2: None, + n: 2, + }, +]; +pub unsafe fn check_local_static_0() { + static mut local_outer: Outer = Outer { + p1: std::ptr::null_mut(), + p2: std::ptr::null(), + arr: [std::ptr::null_mut(); 3], + cp: std::ptr::null(), + pp: std::ptr::null_mut(), + inner: Inner { + v: 0_i32, + name: std::ptr::null(), + }, + x: 0_i32, + fn_: None, + };; + static mut local_fn: Option i32> = None;; + static mut local_p: *mut i32 = std::ptr::null_mut();; + assert!((local_outer.p1).is_null()); + assert!((local_outer.fn_).is_none()); + assert!((local_fn).is_none()); + assert!((local_p).is_null()); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + assert!((static_p1).is_null()); + assert!((static_p2).is_null()); + assert!((static_cp).is_null()); + let mut i: i32 = 0; + 'loop_: while ((i) < (4)) { + assert!((static_arr[(i) as usize]).is_null()); + i.prefix_inc(); + } + assert!((static_pp).is_null()); + assert!((static_fn).is_none()); + assert!((static_outer.p1).is_null()); + assert!((static_outer.p2).is_null()); + assert!((static_outer.cp).is_null()); + assert!((static_outer.pp).is_null()); + assert!((static_outer.fn_).is_none()); + let mut i: i32 = 0; + 'loop_: while ((i) < (3)) { + assert!((static_outer.arr[(i) as usize]).is_null()); + i.prefix_inc(); + } + assert!((static_outer.inner.name).is_null()); + let mut i: i32 = 0; + 'loop_: while ((i) < (2)) { + assert!((static_inner_array[(i) as usize].name).is_null()); + i.prefix_inc(); + } + assert!((static_foo.s2).is_null()); + assert!((static_foo.fn1).is_none()); + assert!((static_foo.fn2).is_none()); + assert!(((static_foo.n) == (42))); + let mut i: i32 = 0; + 'loop_: while ((i) < (2)) { + assert!((static_foo_array[(i) as usize].s2).is_null()); + assert!((static_foo_array[(i) as usize].fn1).is_none()); + assert!((static_foo_array[(i) as usize].fn2).is_none()); + i.prefix_inc(); + } + (unsafe { check_local_static_0() }); + return 0; +} From d59191ba5cf83703e6a73afa0035616733fcd942 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sun, 10 May 2026 15:20:49 +0100 Subject: [PATCH 3/4] Update tests --- tests/unit/out/refcount/default_in_statics.rs | 28 ------------------- tests/unit/out/unsafe/default_in_statics.rs | 14 ---------- 2 files changed, 42 deletions(-) diff --git a/tests/unit/out/refcount/default_in_statics.rs b/tests/unit/out/refcount/default_in_statics.rs index a51d0029..73585127 100644 --- a/tests/unit/out/refcount/default_in_statics.rs +++ b/tests/unit/out/refcount/default_in_statics.rs @@ -98,25 +98,6 @@ impl Default for Foo { } } impl ByteRepr for Foo {} -thread_local!( - pub static static_p1: Value> = Rc::new(RefCell::new(Ptr::::null())); -); -thread_local!( - pub static static_p2: Value> = Rc::new(RefCell::new(Ptr::::null())); -); -thread_local!( - pub static static_cp: Value> = Rc::new(RefCell::new(Ptr::::null())); -); -thread_local!( - pub static static_arr: Value]>> = Rc::new(RefCell::new( - (0..4) - .map(|_| Ptr::::null()) - .collect::]>>(), - )); -); -thread_local!( - pub static static_pp: Value>> = Rc::new(RefCell::new(Ptr::>::null())); -); thread_local!( pub static static_fn: Value i32>> = Rc::new(RefCell::new(FnPtr::null())); ); @@ -174,15 +155,6 @@ pub fn main() { std::process::exit(main_0()); } fn main_0() -> i32 { - assert!((*static_p1.with(Value::clone).borrow()).is_null()); - assert!((*static_p2.with(Value::clone).borrow()).is_null()); - assert!((*static_cp.with(Value::clone).borrow()).is_null()); - let i: Value = Rc::new(RefCell::new(0)); - 'loop_: while ((*i.borrow()) < 4) { - assert!(((*static_arr.with(Value::clone).borrow())[(*i.borrow()) as usize]).is_null()); - (*i.borrow_mut()).prefix_inc(); - } - assert!((*static_pp.with(Value::clone).borrow()).is_null()); assert!((*static_fn.with(Value::clone).borrow()).is_null()); assert!((*(*static_outer.with(Value::clone).borrow()).p1.borrow()).is_null()); assert!((*(*static_outer.with(Value::clone).borrow()).p2.borrow()).is_null()); diff --git a/tests/unit/out/unsafe/default_in_statics.rs b/tests/unit/out/unsafe/default_in_statics.rs index d2d96390..4f21ffe7 100644 --- a/tests/unit/out/unsafe/default_in_statics.rs +++ b/tests/unit/out/unsafe/default_in_statics.rs @@ -58,11 +58,6 @@ impl Default for Foo { } } } -pub static mut static_p1: *mut i32 = std::ptr::null_mut(); -pub static mut static_p2: *const i32 = std::ptr::null(); -pub static mut static_cp: *const u8 = std::ptr::null(); -pub static mut static_arr: [*mut i32; 4] = [std::ptr::null_mut(); 4]; -pub static mut static_pp: *mut *mut i32 = std::ptr::null_mut(); pub static mut static_fn: Option i32> = None; pub static mut static_outer: Outer = Outer { p1: std::ptr::null_mut(), @@ -131,15 +126,6 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - assert!((static_p1).is_null()); - assert!((static_p2).is_null()); - assert!((static_cp).is_null()); - let mut i: i32 = 0; - 'loop_: while ((i) < (4)) { - assert!((static_arr[(i) as usize]).is_null()); - i.prefix_inc(); - } - assert!((static_pp).is_null()); assert!((static_fn).is_none()); assert!((static_outer.p1).is_null()); assert!((static_outer.p2).is_null()); From 89d857280a0471370ad4069ff882709a8ab46afb Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sun, 10 May 2026 15:33:46 +0100 Subject: [PATCH 4/4] Fix release build --- cpp2rust/converter/converter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index e9cf7b92..7fc23c5c 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -3048,7 +3048,7 @@ std::string Converter::GetDefaultAsStringFallback(clang::QualType qual_type) { if (auto record = qual_type->getAsRecordDecl(); record && in_const_initializer_) { if (auto cxx = clang::dyn_cast(record)) { - assert(GetUserDefinedDefaultConstructor(cxx) == nullptr && + ENSURE(GetUserDefinedDefaultConstructor(cxx) == nullptr && "Default initializing globals using default constructor is not " "supported"); }