Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ bool Converter::NeedsMut(const clang::VarDecl *decl, clang::QualType type,
auto *method_or_null =
curr_function_ ? clang::dyn_cast<clang::CXXMethodDecl>(curr_function_)
: nullptr;
return ((hoisted_decls_.contains(decl) ||
return ((hoisted_decls_.contains(decl) || NeedsScopedDestructor(decl) ||
(!type.isConstQualified() && !type->isReferenceType())) &&
((method_or_null == nullptr) || !method_or_null->isVirtual()) &&
!IsGlobalVar(decl) && name != "_");
Expand Down Expand Up @@ -627,8 +627,21 @@ bool Converter::VisitVarDecl(clang::VarDecl *decl) {
return false;
}

void Converter::EmitScopedDestructor(const clang::VarDecl *decl) {
bool Converter::NeedsScopedDestructor(const clang::VarDecl *decl) const {
if (in_function_formals_ || !decl->isLocalVarDecl() || IsGlobalVar(decl)) {
return false;
}
auto type = decl->getType();
if (auto lambda = AsLambdaClass(type);
lambda && LambdaNeedsDestruction(lambda)) {
return true;
}
return !type->isReferenceType() && !type->isArrayType() &&
TypeNeedsDestruction(type);
}

void Converter::EmitScopedDestructor(const clang::VarDecl *decl) {
if (!NeedsScopedDestructor(decl)) {
return;
}
auto type = decl->getType();
Expand All @@ -640,10 +653,6 @@ void Converter::EmitScopedDestructor(const clang::VarDecl *decl) {
GetNamedDeclAsString(decl)));
return;
}
if (type->isReferenceType() || type->isArrayType() ||
!TypeNeedsDestruction(type)) {
return;
}
auto name = GetNamedDeclAsString(decl);
StrCat(token::kSemiColon,
std::format("let _dtor_{0} = ScopedDestructorUnsafe::new(&raw mut "
Expand Down
2 changes: 2 additions & 0 deletions cpp2rust/converter/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {

virtual std::string DestroyMembers(const clang::CXXRecordDecl *decl);

bool NeedsScopedDestructor(const clang::VarDecl *decl) const;

virtual void EmitScopedDestructor(const clang::VarDecl *decl);

void EmitDeallocation(clang::CXXDeleteExpr *expr,
Expand Down
7 changes: 7 additions & 0 deletions tests/unit/destructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,12 @@ int main() {
assert(order[1] == 2);
assert(order[2] == 1);

int before = global;
{
const S cs;
(void)cs;
}
assert(global == before + 1);

return 0;
}
7 changes: 7 additions & 0 deletions tests/unit/out/refcount/destructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ fn main_0() -> i32 {
order_1.with(|rc| rc.borrow()[__idx])
}) == 1)
);
let mut before: i32 = global_0.with(|rc| *rc.borrow());
{
let cs: Value<S> = Rc::new(RefCell::new(<S>::default()));
let _dtor_cs = ScopedDestructor::new(&cs, |__p| __p.destructor());
&(*cs.borrow_mut());
}
assert!((global_0.with(|rc| *rc.borrow()) == (before + 1)));
return 0;
}
pub trait ArrayMemberImpl {
Expand Down
7 changes: 7 additions & 0 deletions tests/unit/out/unsafe/destructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,13 @@ unsafe fn main_0() -> i32 {
assert!((((*std::cell::LazyCell::force_mut(&mut *&raw mut order_1))[(0) as usize]) == (3)));
assert!((((*std::cell::LazyCell::force_mut(&mut *&raw mut order_1))[(1) as usize]) == (2)));
assert!((((*std::cell::LazyCell::force_mut(&mut *&raw mut order_1))[(2) as usize]) == (1)));
let mut before: i32 = (*std::cell::LazyCell::force_mut(&mut *&raw mut global_0));
{
let mut cs: S = <S>::default();
let _dtor_cs = ScopedDestructorUnsafe::new(&raw mut cs, S::destructor);
&(cs);
}
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut global_0)) == ((before) + (1))));
return 0;
}
pub unsafe fn __cpp2rust_init_globals() {
Expand Down
Loading