diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 655a6020..042f5994 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -381,7 +381,8 @@ bool Converter::ConvertVarDeclSkipInit(clang::VarDecl *decl) { if (decl->isFileVarDecl()) { name = ReplaceAll(Mapper::ToString(decl), "::", "_"); - if ((decl->isExternallyDeclarable() && !decl->hasInit()) || + if (decl->isThisDeclarationADefinition() == + clang::VarDecl::DeclarationOnly || !globals_.insert(name).second) { return false; } diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 44eb4cc0..050f887b 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1635,8 +1635,8 @@ std::string ConverterRefCount::GetDefaultAsString(clang::QualType qual_type) { if (pointee_type->isVoidType()) { ret = "AnyPtr::default()"; } else { - ret = std::format("Ptr::<{}>::null()", - GetUnsafeTypeAsString(pointee_type)); + PushConversionKind push(*this, ConversionKind::Unboxed); + ret = std::format("Ptr::<{}>::null()", ConvertPointeeType(qual_type)); } } } else if (auto *array_type = @@ -2240,6 +2240,7 @@ std::string ConverterRefCount::ConvertMappedMethodCall( } std::string ConverterRefCount::ConvertPointeeType(clang::QualType ptr_type) { + assert(!ptr_type.isNull() && ptr_type->isPointerType()); if (ptr_type->getPointeeType()->isIntegerType()) { return ToString(ptr_type->getPointeeType()); } @@ -2247,7 +2248,6 @@ std::string ConverterRefCount::ConvertPointeeType(clang::QualType ptr_type) { // Pointee of a pointer to incomplete type is an incomplete type that does // not have a translation rule. Hence ToString(ptr_type->getPointeeType()) is // not enough - assert(ptr_type->isPointerType()); auto str = ToString(ptr_type); Unwrap(str, "Ptr<", ">"); return str; diff --git a/tests/unit/global_without_initializer.cpp b/tests/unit/global_without_initializer.cpp new file mode 100644 index 00000000..c3e36ba7 --- /dev/null +++ b/tests/unit/global_without_initializer.cpp @@ -0,0 +1,17 @@ +#include +#include + +struct S { + int a; +}; + +S *s; +FILE *file; +size_t size; + +int main() { + assert(s == nullptr); + assert(file == nullptr); + assert(size == 0); + return 0; +}; diff --git a/tests/unit/out/refcount/global_without_initializer.rs b/tests/unit/out/refcount/global_without_initializer.rs new file mode 100644 index 00000000..52ae0d1e --- /dev/null +++ b/tests/unit/out/refcount/global_without_initializer.rs @@ -0,0 +1,40 @@ +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 S { + pub a: Value, +} +impl Clone for S { + fn clone(&self) -> Self { + let mut this = Self { + a: Rc::new(RefCell::new((*self.a.borrow()))), + }; + this + } +} +impl ByteRepr for S {} +thread_local!( + pub static s: Value> = Rc::new(RefCell::new(Ptr::::null())); +); +thread_local!( + pub static file: Value> = + Rc::new(RefCell::new(Ptr::<::std::fs::File>::null())); +); +thread_local!( + pub static size: Value = >::default(); +); +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + assert!((*s.with(Value::clone).borrow()).is_null()); + assert!((*file.with(Value::clone).borrow()).is_null()); + assert!(((*size.with(Value::clone).borrow()) == 0_u64)); + return 0; +} diff --git a/tests/unit/out/unsafe/global_without_initializer.rs b/tests/unit/out/unsafe/global_without_initializer.rs new file mode 100644 index 00000000..57c51700 --- /dev/null +++ b/tests/unit/out/unsafe/global_without_initializer.rs @@ -0,0 +1,27 @@ +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 S { + pub a: i32, +} +pub static mut s: *mut S = std::ptr::null_mut(); +pub static mut file: *mut ::std::fs::File = std::ptr::null_mut(); +pub static mut size: u64 = 0_u64; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + assert!((s).is_null()); + assert!((file).is_null()); + assert!(((size) == (0_u64))); + return 0; +}