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
27 changes: 18 additions & 9 deletions cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -2005,17 +2005,20 @@ 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()
? arr_size - expr->getString().size()
: 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')) {
Expand All @@ -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;
}

Expand Down Expand Up @@ -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() &&
Expand Down Expand Up @@ -2408,6 +2416,7 @@ void Converter::ConvertBinaryOperator(clang::BinaryOperator *expr) {
PushParen paren(*this);
ConvertCondition(expr->getRHS());
}
computed_expr_type_ = ComputedExprType::FreshValue;
} else {
ConvertGenericBinaryOperator(expr);
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 8 additions & 2 deletions cpp2rust/converter/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,13 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
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);
Expand Down Expand Up @@ -602,7 +608,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {

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);

Expand Down
20 changes: 19 additions & 1 deletion cpp2rust/converter/models/converter_refcount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down Expand Up @@ -788,6 +789,7 @@ bool ConverterRefCount::ConvertIncAndDec(clang::UnaryOperator *expr) {
} else {
StrCat(str, '.', method, "()");
}
SetFreshType(expr->getType());
return true;
}

Expand Down Expand Up @@ -1133,16 +1135,19 @@ 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()
? arr_size - expr->getString().size()
: 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;
}

Expand Down Expand Up @@ -1270,6 +1275,7 @@ void ConverterRefCount::ConvertEqualsNullPtr(clang::Expr *expr) {
StrCat('(');
Convert(expr);
StrCat(").is_null()");
computed_expr_type_ = ComputedExprType::FreshValue;
}

bool ConverterRefCount::VisitFunctionPointerCast(
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -1882,6 +1892,7 @@ bool ConverterRefCount::VisitImplicitValueInitExpr(
StrCat("Box::new(");
Converter::VisitImplicitValueInitExpr(expr);
StrCat(')');
computed_expr_type_ = ComputedExprType::FreshValue;
return false;
}
}
Expand Down Expand Up @@ -1909,6 +1920,7 @@ bool ConverterRefCount::VisitVAArgExpr(clang::VAArgExpr *expr) {
StrCat(ToString(expr->getType()));
}
StrCat(">()");
SetFreshType(expr->getType());
return false;
}

Expand Down Expand Up @@ -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));
}

Expand All @@ -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));
}

Expand Down Expand Up @@ -2103,13 +2118,15 @@ void ConverterRefCount::ConvertGenericBinaryOperator(
opcode,
ConvertFreshRValue(
rhs, GetOperandImplicitConversionTarget(expr, rhs, lhs))));
computed_expr_type_ = ComputedExprType::FreshValue;
return;
}

PushParen outer(*this);
Convert(lhs, GetOperandImplicitConversionTarget(expr, lhs, rhs));
StrCat(opcode);
Convert(rhs, GetOperandImplicitConversionTarget(expr, rhs, lhs));
computed_expr_type_ = ComputedExprType::FreshValue;
}

void ConverterRefCount::ConvertUniquePtrDeref(
Expand Down Expand Up @@ -2374,7 +2391,7 @@ void ConverterRefCount::ConvertDeref(clang::Expr *expr) {
Convert(expr);
if (deref) {
StrCat(GetPointerDerefSuffix(pointee_type));
SetValueFreshness(expr->getType());
SetValueFreshness(pointee_type);
}
}

Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,5 @@ impl ByteRepr for widget_enum {
}
pub fn b_value_1() -> i32 {
let w: Value<widget_enum> = Rc::new(RefCell::new(widget_enum::WIDGET_C));
return ((*w.borrow()) as i32).clone();
return ((*w.borrow()) as i32);
}
2 changes: 1 addition & 1 deletion tests/unit/out/refcount/anonymous_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/out/refcount/bool_condition_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn main_0() -> i32 {
}
let t9: Value<i32> = Rc::new(RefCell::new((!((*code.borrow()) != Code::from(0)) as i32)));
assert!(((*t9.borrow()) == 1));
let b4: Value<bool> = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0)).clone()));
let b4: Value<bool> = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0))));
assert!(!(*b4.borrow()));
return 0;
}
2 changes: 1 addition & 1 deletion tests/unit/out/refcount/bool_condition_enum_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn main_0() -> i32 {
}
let t9: Value<i32> = Rc::new(RefCell::new((!((*code.borrow()) != Code::from(0)) as i32)));
assert!(((((*t9.borrow()) == 1) as i32) != 0));
let b4: Value<bool> = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0)).clone()));
let b4: Value<bool> = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0))));
assert!(((!(*b4.borrow()) as i32) != 0));
return 0;
}
4 changes: 2 additions & 2 deletions tests/unit/out/refcount/bool_condition_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ fn main_0() -> i32 {
assert!(((*t5.borrow()) == 0));
let t6: Value<i32> = Rc::new(RefCell::new((!!(*np.borrow()).is_null() as i32)));
assert!(((*t6.borrow()) == 1));
let b2: Value<bool> = Rc::new(RefCell::new((!(*p.borrow()).is_null()).clone()));
let b3: Value<bool> = Rc::new(RefCell::new((!(*np.borrow()).is_null()).clone()));
let b2: Value<bool> = Rc::new(RefCell::new(!(*p.borrow()).is_null()));
let b3: Value<bool> = Rc::new(RefCell::new(!(*np.borrow()).is_null()));
assert!((*b2.borrow()));
assert!(!(*b3.borrow()));
return 0;
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/out/refcount/bool_condition_ptr_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ fn main_0() -> i32 {
assert!(((((*t5.borrow()) == 0) as i32) != 0));
let t6: Value<i32> = Rc::new(RefCell::new((!!(*np.borrow()).is_null() as i32)));
assert!(((((*t6.borrow()) == 1) as i32) != 0));
let b2: Value<bool> = Rc::new(RefCell::new((!(*p.borrow()).is_null()).clone()));
let b3: Value<bool> = Rc::new(RefCell::new((!(*np.borrow()).is_null()).clone()));
let b2: Value<bool> = Rc::new(RefCell::new(!(*p.borrow()).is_null()));
let b3: Value<bool> = Rc::new(RefCell::new(!(*np.borrow()).is_null()));
assert!((*b2.borrow()));
assert!(((!(*b3.borrow()) as i32) != 0));
return 0;
Expand Down
Loading
Loading