diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index c62ed111..59410ced 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -669,7 +669,7 @@ bool Converter::RecordDerivesDefault(const clang::RecordDecl *decl) { return true; } -bool Converter::RecordDerivesCopy(const clang::RecordDecl *decl) { +bool Converter::RecordDerivesCopy(const clang::RecordDecl *decl) const { auto *derives = Mapper::MappedDerives(ctx_.getCanonicalTagType(decl)); return derives && std::find(derives->begin(), derives->end(), "Copy") != derives->end(); @@ -2005,6 +2005,7 @@ bool Converter::VisitStringLiteral(clang::StringLiteral *expr) { uint64_t arr_size = arr_ty->getSize().getZExtValue(); if (expr->getString().empty()) { StrCat(std::format("[0 as libc::c_char; {}]", arr_size)); + computed_expr_type_ = ComputedExprType::FreshValue; return false; } uint64_t pad = arr_size > expr->getString().size() @@ -2012,10 +2013,12 @@ bool Converter::VisitStringLiteral(clang::StringLiteral *expr) { : 0; StrCat(std::format("std::mem::transmute(*b{})", GetEscapedStringLiteral(expr, pad))); + computed_expr_type_ = ComputedExprType::FreshValue; return false; } StrCat(std::format("std::mem::transmute(*b{})", GetEscapedStringLiteral(expr, 1))); + computed_expr_type_ = ComputedExprType::FreshValue; return false; } if (expr->getString().contains('\0')) { @@ -2025,9 +2028,11 @@ bool Converter::VisitStringLiteral(clang::StringLiteral *expr) { } out += getTypedLiteral("0", CharRustType()) + "])"; StrCat(out); + computed_expr_type_ = ComputedExprType::FreshValue; return false; } StrCat(std::format("c{}", GetEscapedStringLiteral(expr, 0))); + computed_expr_type_ = ComputedExprType::FreshValue; return false; } @@ -2349,6 +2354,9 @@ void Converter::ConvertBinaryOperator(clang::BinaryOperator *expr) { ConvertUnsignedArithOperand(lhs, type); } ConvertUnsignedArithBinaryOperator(expr, rhs); + if (!expr->isCompoundAssignmentOp()) { + computed_expr_type_ = ComputedExprType::FreshValue; + } } else if (expr->isAssignmentOp()) { if (expr->isCompoundAssignmentOp() && expr->getLHS()->getType()->isPointerType() && @@ -2408,6 +2416,7 @@ void Converter::ConvertBinaryOperator(clang::BinaryOperator *expr) { PushParen paren(*this); ConvertCondition(expr->getRHS()); } + computed_expr_type_ = ComputedExprType::FreshValue; } else { ConvertGenericBinaryOperator(expr); } @@ -2429,6 +2438,7 @@ void Converter::ConvertGenericBinaryOperator(clang::BinaryOperator *expr) { PushParen rhs_paren(*this); Convert(rhs, GetOperandImplicitConversionTarget(expr, rhs, lhs)); } + computed_expr_type_ = ComputedExprType::FreshValue; } bool Converter::IsReferenceType(const clang::Expr *expr) const { @@ -2991,12 +3001,14 @@ bool Converter::VisitVAArgExpr(clang::VAArgExpr *expr) { Convert(va_list_expr); } StrCat(".arg::<*mut ::libc::c_void>()"); + SetFreshType(expr->getType()); return false; } Convert(va_list_expr); StrCat(".arg::<"); Convert(expr->getType()); StrCat(">()"); + SetFreshType(expr->getType()); return false; } @@ -3246,6 +3258,7 @@ void Converter::AddIncDecImpls(clang::EnumDecl *decl) { bool Converter::VisitCXXDefaultArgExpr(clang::CXXDefaultArgExpr *expr) { if (expr->getType()->isPointerType()) { StrCat(token::kDefault); + computed_expr_type_ = ComputedExprType::FreshPointer; } return false; } @@ -3278,11 +3291,13 @@ bool Converter::VisitImplicitValueInitExpr(clang::ImplicitValueInitExpr *expr) { auto elem_ty = const_arr_ty->getElementType(); if (elem_ty->isIntegerType() && !elem_ty->isEnumeralType()) { StrCat(std::format("[0; {}]", const_arr_ty->getSize().getZExtValue())); + computed_expr_type_ = ComputedExprType::FreshValue; return false; } StrCat( std::format("std::array::from_fn::<_, {}, _>(|_| Default::default())", const_arr_ty->getSize().getZExtValue())); + computed_expr_type_ = ComputedExprType::FreshValue; return false; } } @@ -3681,6 +3696,7 @@ void Converter::ConvertEqualsNullPtr(clang::Expr *expr) { } else { StrCat(").is_null()"); } + computed_expr_type_ = ComputedExprType::FreshValue; } void Converter::ConvertPointerSubscript(clang::ArraySubscriptExpr *expr) { @@ -4378,15 +4394,8 @@ void Converter::SetFresh() { } } -static bool hasCopyTrait(clang::QualType type) { - if (type->isBuiltinType()) - return true; - - return false; -} - void Converter::SetValueFreshness(clang::QualType type) { - if (hasCopyTrait(type)) { + if (TypeIsCopyable(type)) { computed_expr_type_ = ComputedExprType::FreshValue; } else if (type->isPointerType() || type->isReferenceType()) { computed_expr_type_ = ComputedExprType::Pointer; diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index d15f19c9..8a55ef2b 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -279,7 +279,13 @@ class Converter : public clang::RecursiveASTVisitor { if (ty->isFunctionPointerType() || ty->isFunctionType()) { return FunctionPointerImplementsCopy(); } - return ty->isIntegerType(); + if (ty->isBuiltinType() || ty->isEnumeralType()) { + return true; + } + if (auto *record = ty->getAsRecordDecl()) { + return RecordDerivesCopy(record); + } + return false; } virtual void ConvertPrintf(clang::CallExpr *expr); @@ -602,7 +608,7 @@ class Converter : public clang::RecursiveASTVisitor { virtual bool RecordDerivesDefault(const clang::RecordDecl *decl); - bool RecordDerivesCopy(const clang::RecordDecl *decl); + bool RecordDerivesCopy(const clang::RecordDecl *decl) const; bool RecordHasCopyableFields(const clang::RecordDecl *decl); diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 15a10b5a..2e33e5f5 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -402,6 +402,7 @@ bool ConverterRefCount::VisitArraySubscriptExpr( StrCat(GetPointerDerefPrefix(expr->getType())); ConvertArraySubscript(base, expr->getIdx(), expr->getType()); StrCat(GetPointerDerefSuffix(expr->getType())); + SetValueFreshness(expr->getType()); } else { ConvertArraySubscript(base, expr->getIdx(), expr->getType()); } @@ -788,6 +789,7 @@ bool ConverterRefCount::ConvertIncAndDec(clang::UnaryOperator *expr) { } else { StrCat(str, '.', method, "()"); } + SetFreshType(expr->getType()); return true; } @@ -1133,6 +1135,7 @@ bool ConverterRefCount::VisitStringLiteral(clang::StringLiteral *expr) { uint64_t arr_size = arr_ty->getSize().getZExtValue(); if (expr->getString().empty()) { StrCat(std::format("vec![0u8; {}].into_boxed_slice()", arr_size)); + computed_expr_type_ = ComputedExprType::FreshValue; return false; } pad = arr_size > expr->getString().size() @@ -1140,9 +1143,11 @@ bool ConverterRefCount::VisitStringLiteral(clang::StringLiteral *expr) { : 0; } StrCat(std::format("Box::from(*b{})", GetEscapedStringLiteral(expr, pad))); + computed_expr_type_ = ComputedExprType::FreshValue; return false; } StrCat(std::format("b{}", GetEscapedStringLiteral(expr, 0))); + computed_expr_type_ = ComputedExprType::FreshValue; return false; } @@ -1270,6 +1275,7 @@ void ConverterRefCount::ConvertEqualsNullPtr(clang::Expr *expr) { StrCat('('); Convert(expr); StrCat(").is_null()"); + computed_expr_type_ = ComputedExprType::FreshValue; } bool ConverterRefCount::VisitFunctionPointerCast( @@ -1421,6 +1427,7 @@ void ConverterRefCount::EmitStmtExprTail(clang::Expr *tail) { Convert(tail); StrCat(token::kSemiColon); StrCat("__result"); + SetFreshType(tail->getType()); } void ConverterRefCount::ConvertBinaryOperator(clang::BinaryOperator *expr) { @@ -1483,6 +1490,8 @@ void ConverterRefCount::ConvertBinaryOperator(clang::BinaryOperator *expr) { if (expr->isCompoundAssignmentOp()) { StrCat(token::kSemiColon); EmitSetOrAssign(lhs, "rhs_0"); + } else { + computed_expr_type_ = ComputedExprType::FreshValue; } return; } @@ -1608,6 +1617,7 @@ void ConverterRefCount::ConvertUnionMemberAccessor(clang::MemberExpr *expr) { return; } StrCat(DerefPtrExpr(str, member->getType())); + SetValueFreshness(member->getType()); } bool ConverterRefCount::VisitMemberExpr(clang::MemberExpr *expr) { @@ -1882,6 +1892,7 @@ bool ConverterRefCount::VisitImplicitValueInitExpr( StrCat("Box::new("); Converter::VisitImplicitValueInitExpr(expr); StrCat(')'); + computed_expr_type_ = ComputedExprType::FreshValue; return false; } } @@ -1909,6 +1920,7 @@ bool ConverterRefCount::VisitVAArgExpr(clang::VAArgExpr *expr) { StrCat(ToString(expr->getType())); } StrCat(">()"); + SetFreshType(expr->getType()); return false; } @@ -1936,10 +1948,12 @@ ConverterRefCount::GetArrayDefaultAsString(clang::QualType qual_type) { std::string ConverterRefCount::GetDefaultAsString(clang::QualType qual_type) { if (IsVaListType(qual_type)) { + computed_expr_type_ = ComputedExprType::FreshValue; return BoxValue("VaList::default()"); } if (auto arr = GetArrayDefaultAsString(qual_type); !arr.empty()) { + computed_expr_type_ = ComputedExprType::FreshValue; return BoxValue(std::move(arr)); } @@ -1964,6 +1978,7 @@ std::string ConverterRefCount::GetDefaultAsString(clang::QualType qual_type) { } else { return Converter::GetDefaultAsString(qual_type); } + computed_expr_type_ = ComputedExprType::FreshPointer; return BoxValue(std::move(ret)); } @@ -2103,6 +2118,7 @@ void ConverterRefCount::ConvertGenericBinaryOperator( opcode, ConvertFreshRValue( rhs, GetOperandImplicitConversionTarget(expr, rhs, lhs)))); + computed_expr_type_ = ComputedExprType::FreshValue; return; } @@ -2110,6 +2126,7 @@ void ConverterRefCount::ConvertGenericBinaryOperator( Convert(lhs, GetOperandImplicitConversionTarget(expr, lhs, rhs)); StrCat(opcode); Convert(rhs, GetOperandImplicitConversionTarget(expr, rhs, lhs)); + computed_expr_type_ = ComputedExprType::FreshValue; } void ConverterRefCount::ConvertUniquePtrDeref( @@ -2374,7 +2391,7 @@ void ConverterRefCount::ConvertDeref(clang::Expr *expr) { Convert(expr); if (deref) { StrCat(GetPointerDerefSuffix(pointee_type)); - SetValueFreshness(expr->getType()); + SetValueFreshness(pointee_type); } } @@ -2394,6 +2411,7 @@ void ConverterRefCount::ConvertArrow(clang::Expr *expr) { if (!is_overloaded_arrow) { auto ptr = ToString(expr); StrCat(DerefPtrExpr(ptr, expr->getType()->getPointeeType())); + SetValueFreshness(expr->getType()->getPointeeType()); return; } diff --git a/tests/multi-file/cross_tu_tag_collision/out/refcount/cross_tu_tag_collision.rs b/tests/multi-file/cross_tu_tag_collision/out/refcount/cross_tu_tag_collision.rs index f4846e89..3493dcce 100644 --- a/tests/multi-file/cross_tu_tag_collision/out/refcount/cross_tu_tag_collision.rs +++ b/tests/multi-file/cross_tu_tag_collision/out/refcount/cross_tu_tag_collision.rs @@ -71,5 +71,5 @@ impl ByteRepr for widget_enum { } pub fn b_value_1() -> i32 { let w: Value = Rc::new(RefCell::new(widget_enum::WIDGET_C)); - return ((*w.borrow()) as i32).clone(); + return ((*w.borrow()) as i32); } diff --git a/tests/unit/out/refcount/anonymous_enum.rs b/tests/unit/out/refcount/anonymous_enum.rs index 47298b56..780a7f05 100644 --- a/tests/unit/out/refcount/anonymous_enum.rs +++ b/tests/unit/out/refcount/anonymous_enum.rs @@ -136,7 +136,7 @@ impl Clone for WithAnonField { fn clone(&self) -> Self { let mut this = Self { a: Rc::new(RefCell::new((*self.a.borrow()))), - field: Rc::new(RefCell::new((*self.field.borrow()).clone())), + field: Rc::new(RefCell::new((*self.field.borrow()))), }; this } diff --git a/tests/unit/out/refcount/bool_condition_enum.rs b/tests/unit/out/refcount/bool_condition_enum.rs index 228c2f70..540855e4 100644 --- a/tests/unit/out/refcount/bool_condition_enum.rs +++ b/tests/unit/out/refcount/bool_condition_enum.rs @@ -52,7 +52,7 @@ fn main_0() -> i32 { } let t9: Value = Rc::new(RefCell::new((!((*code.borrow()) != Code::from(0)) as i32))); assert!(((*t9.borrow()) == 1)); - let b4: Value = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0)).clone())); + let b4: Value = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0)))); assert!(!(*b4.borrow())); return 0; } diff --git a/tests/unit/out/refcount/bool_condition_enum_c.rs b/tests/unit/out/refcount/bool_condition_enum_c.rs index c22850e6..f8ed68b4 100644 --- a/tests/unit/out/refcount/bool_condition_enum_c.rs +++ b/tests/unit/out/refcount/bool_condition_enum_c.rs @@ -52,7 +52,7 @@ fn main_0() -> i32 { } let t9: Value = Rc::new(RefCell::new((!((*code.borrow()) != Code::from(0)) as i32))); assert!(((((*t9.borrow()) == 1) as i32) != 0)); - let b4: Value = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0)).clone())); + let b4: Value = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0)))); assert!(((!(*b4.borrow()) as i32) != 0)); return 0; } diff --git a/tests/unit/out/refcount/bool_condition_ptr.rs b/tests/unit/out/refcount/bool_condition_ptr.rs index 11703cb8..6fc34386 100644 --- a/tests/unit/out/refcount/bool_condition_ptr.rs +++ b/tests/unit/out/refcount/bool_condition_ptr.rs @@ -40,8 +40,8 @@ fn main_0() -> i32 { assert!(((*t5.borrow()) == 0)); let t6: Value = Rc::new(RefCell::new((!!(*np.borrow()).is_null() as i32))); assert!(((*t6.borrow()) == 1)); - let b2: Value = Rc::new(RefCell::new((!(*p.borrow()).is_null()).clone())); - let b3: Value = Rc::new(RefCell::new((!(*np.borrow()).is_null()).clone())); + let b2: Value = Rc::new(RefCell::new(!(*p.borrow()).is_null())); + let b3: Value = Rc::new(RefCell::new(!(*np.borrow()).is_null())); assert!((*b2.borrow())); assert!(!(*b3.borrow())); return 0; diff --git a/tests/unit/out/refcount/bool_condition_ptr_c.rs b/tests/unit/out/refcount/bool_condition_ptr_c.rs index 95cfedf4..e9bd4bfa 100644 --- a/tests/unit/out/refcount/bool_condition_ptr_c.rs +++ b/tests/unit/out/refcount/bool_condition_ptr_c.rs @@ -40,8 +40,8 @@ fn main_0() -> i32 { assert!(((((*t5.borrow()) == 0) as i32) != 0)); let t6: Value = Rc::new(RefCell::new((!!(*np.borrow()).is_null() as i32))); assert!(((((*t6.borrow()) == 1) as i32) != 0)); - let b2: Value = Rc::new(RefCell::new((!(*p.borrow()).is_null()).clone())); - let b3: Value = Rc::new(RefCell::new((!(*np.borrow()).is_null()).clone())); + let b2: Value = Rc::new(RefCell::new(!(*p.borrow()).is_null())); + let b3: Value = Rc::new(RefCell::new(!(*np.borrow()).is_null())); assert!((*b2.borrow())); assert!(((!(*b3.borrow()) as i32) != 0)); return 0; diff --git a/tests/unit/out/refcount/enum_int_interop.rs b/tests/unit/out/refcount/enum_int_interop.rs index e8c088e5..99a43eef 100644 --- a/tests/unit/out/refcount/enum_int_interop.rs +++ b/tests/unit/out/refcount/enum_int_interop.rs @@ -96,8 +96,8 @@ impl Clone for Entry { fn clone(&self) -> Self { let mut this = Self { name: Rc::new(RefCell::new((*self.name.borrow()).clone())), - color: Rc::new(RefCell::new((*self.color.borrow()).clone())), - opt: Rc::new(RefCell::new((*self.opt.borrow()).clone())), + color: Rc::new(RefCell::new((*self.color.borrow()))), + opt: Rc::new(RefCell::new((*self.opt.borrow()))), }; this } @@ -149,7 +149,7 @@ thread_local!( ); pub fn as_int_4(c: Color) -> i32 { let c: Value = Rc::new(RefCell::new(c)); - return ((*c.borrow()) as i32).clone(); + return ((*c.borrow()) as i32); } pub fn classify_option_5(option: i32) -> i32 { let option: Value = Rc::new(RefCell::new(option)); @@ -207,7 +207,7 @@ fn main_0() -> i32 { } } }; - let x: Value = Rc::new(RefCell::new(((*c.borrow()) as i32).clone())); + let x: Value = Rc::new(RefCell::new(((*c.borrow()) as i32))); assert!(((*x.borrow()) == 0)); let y: Value = Rc::new(RefCell::new((((*c.borrow()) as i32) + 1))); assert!(((*y.borrow()) == 1)); @@ -221,12 +221,12 @@ fn main_0() -> i32 { let o: Value