diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 65929016..37f474ad 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2274,7 +2274,8 @@ void Converter::ConvertBinaryOperator(clang::BinaryOperator *expr) { if (auto *cmpd_assign_op = llvm::dyn_cast(expr); expr->isCompoundAssignmentOp() && - lhs_type != cmpd_assign_op->getComputationResultType()) { + GetUnsafeTypeAsString(lhs_type) != + GetUnsafeTypeAsString(cmpd_assign_op->getComputationResultType())) { auto computation_result_type = cmpd_assign_op->getComputationResultType(); if (IsUnsignedArithOp(cmpd_assign_op)) { Convert(lhs); diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index de3463c5..c7a2be2b 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -109,6 +109,14 @@ ConverterRefCount::PushUnboxedIfSimple::PushUnboxedIfSimple( : ConversionKind::FullRefCount); } +std::string +ConverterRefCount::GetSafeTypeAsString(clang::QualType qual_type) const { + std::string type_as_string; + ConverterRefCount converter(type_as_string, ctx_); + converter.Convert(qual_type); + return std::string(Trim(type_as_string)); +} + std::string ConverterRefCount::BoxType(std::string &&str) const { switch (getConversionKind()) { case ConversionKind::Unboxed: @@ -1362,7 +1370,8 @@ void ConverterRefCount::ConvertBinaryOperator(clang::BinaryOperator *expr) { std::string_view opcode_as_string = expr->getOpcodeStr(); if (auto *assign = llvm::dyn_cast(expr); - assign && lhs_type != assign->getComputationResultType()) { + assign && GetSafeTypeAsString(lhs_type) != + GetSafeTypeAsString(assign->getComputationResultType())) { auto computation_result_type = assign->getComputationResultType(); StrCat(keyword::kLet, "rhs_0", token::kAssign); if (IsUnsignedArithOp(assign)) { diff --git a/cpp2rust/converter/models/converter_refcount.h b/cpp2rust/converter/models/converter_refcount.h index 819fa4ff..e58853e1 100644 --- a/cpp2rust/converter/models/converter_refcount.h +++ b/cpp2rust/converter/models/converter_refcount.h @@ -242,6 +242,8 @@ class ConverterRefCount final : public Converter { std::string ConvertPtrType(clang::QualType type); std::string ConvertPointeeType(clang::QualType ptr_type) override; + std::string GetSafeTypeAsString(clang::QualType qual_type) const; + /// The kind of conversion that should be performed. enum class ConversionKind : uint8_t { Unboxed, diff --git a/tests/unit/compound_assign_ref.cpp b/tests/unit/compound_assign_ref.cpp new file mode 100644 index 00000000..59125dbb --- /dev/null +++ b/tests/unit/compound_assign_ref.cpp @@ -0,0 +1,13 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +#include +#include + +int main() { + std::vector v; + v.push_back(10); + v.front() += 5; + assert(v.front() == 15); + return v.front(); +} diff --git a/tests/unit/out/refcount/auto.rs b/tests/unit/out/refcount/auto.rs index cdeac07a..ded6317c 100644 --- a/tests/unit/out/refcount/auto.rs +++ b/tests/unit/out/refcount/auto.rs @@ -19,8 +19,7 @@ fn main_0() -> i32 { let sum: Value = Rc::new(RefCell::new(0)); 'loop_: for mut elem in v.as_pointer() as Ptr { let elem: Value = Rc::new(RefCell::new(elem.read().clone())); - let rhs_0 = (((*sum.borrow()) as i32) + (*elem.borrow())) as i32; - (*sum.borrow_mut()) = rhs_0; + (*sum.borrow_mut()) += (*elem.borrow()); } return (*sum.borrow()); } diff --git a/tests/unit/out/refcount/compound_assign_ref.rs b/tests/unit/out/refcount/compound_assign_ref.rs new file mode 100644 index 00000000..de0dbe55 --- /dev/null +++ b/tests/unit/out/refcount/compound_assign_ref.rs @@ -0,0 +1,21 @@ +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}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let v: Value> = Rc::new(RefCell::new(Vec::new())); + (*v.borrow_mut()).push(10); + { + let _ptr = (v.as_pointer() as Ptr).clone(); + _ptr.write(_ptr.read() + 5) + }; + assert!((((v.as_pointer() as Ptr).read()) == 15)); + return ((v.as_pointer() as Ptr).read()); +} diff --git a/tests/unit/out/refcount/foreach_mut.rs b/tests/unit/out/refcount/foreach_mut.rs index a96aa7bf..0a65f06e 100644 --- a/tests/unit/out/refcount/foreach_mut.rs +++ b/tests/unit/out/refcount/foreach_mut.rs @@ -24,8 +24,10 @@ fn main_0() -> i32 { (*sum.borrow_mut()) += (*x.borrow()); } 'loop_: for mut x in v1.as_pointer() as Ptr { - let rhs_0 = (((x.read()) as i32) + 10) as i32; - x.write(rhs_0); + { + let _ptr = x.clone(); + _ptr.write(_ptr.read() + 10) + }; } 'loop_: for mut x in v1.as_pointer() as Ptr { let __rhs = (x.read()); @@ -49,8 +51,10 @@ fn main_0() -> i32 { } 'loop_: for mut p in v2.as_pointer() as Ptr> { let p: Value> = Rc::new(RefCell::new(p.read().clone())); - let rhs_0 = ((((*p.borrow()).read()) as i32) + 5) as i32; - (*p.borrow()).write(rhs_0); + { + let _ptr = (*p.borrow()).clone(); + _ptr.write(_ptr.read() + 5) + }; } 'loop_: for mut p in v2.as_pointer() as Ptr> { let p: Value> = Rc::new(RefCell::new(p.read().clone())); diff --git a/tests/unit/out/refcount/unique_ptr_deref_ops.rs b/tests/unit/out/refcount/unique_ptr_deref_ops.rs index 128ad6ad..e311ab90 100644 --- a/tests/unit/out/refcount/unique_ptr_deref_ops.rs +++ b/tests/unit/out/refcount/unique_ptr_deref_ops.rs @@ -11,12 +11,9 @@ pub fn main() { } fn main_0() -> i32 { let p: Value>> = Rc::new(RefCell::new(Some(Rc::new(RefCell::new(10))))); - let rhs_0 = (((*(*p.borrow()).as_ref().unwrap().borrow()) as i32) + 5) as i32; - (*(*p.borrow_mut()).as_ref().unwrap().borrow_mut()) = rhs_0; - let rhs_0 = (((*(*p.borrow()).as_ref().unwrap().borrow()) as i32) - 3) as i32; - (*(*p.borrow_mut()).as_ref().unwrap().borrow_mut()) = rhs_0; - let rhs_0 = (((*(*p.borrow()).as_ref().unwrap().borrow()) as i32) * 2) as i32; - (*(*p.borrow_mut()).as_ref().unwrap().borrow_mut()) = rhs_0; + (*(*p.borrow_mut()).as_ref().unwrap().borrow_mut()) += 5; + (*(*p.borrow_mut()).as_ref().unwrap().borrow_mut()) -= 3; + (*(*p.borrow_mut()).as_ref().unwrap().borrow_mut()) *= 2; let q: Value>> = Rc::new(RefCell::new(Some(Rc::new(RefCell::new(1))))); let sum: Value = Rc::new(RefCell::new( ((*(*p.borrow()).as_ref().unwrap().borrow()) + (*(*q.borrow()).as_ref().unwrap().borrow())), diff --git a/tests/unit/out/unsafe/auto.rs b/tests/unit/out/unsafe/auto.rs index 9fe1ce28..5d206ab3 100644 --- a/tests/unit/out/unsafe/auto.rs +++ b/tests/unit/out/unsafe/auto.rs @@ -21,7 +21,7 @@ unsafe fn main_0() -> i32 { let mut sum: i32 = 0; 'loop_: for elem in 0..(v.len()) { let mut elem = v[elem].clone(); - sum = ((sum as i32) + elem) as i32; + sum += elem; } return sum; } diff --git a/tests/unit/out/unsafe/compound_assign_ref.rs b/tests/unit/out/unsafe/compound_assign_ref.rs new file mode 100644 index 00000000..9f7639ff --- /dev/null +++ b/tests/unit/out/unsafe/compound_assign_ref.rs @@ -0,0 +1,20 @@ +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; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut v: Vec = Vec::new(); + v.push(10); + (*((v).first_mut().unwrap())) += 5; + assert!(((*((v).first_mut().unwrap())) == (15))); + return (*((v).first_mut().unwrap())); +} diff --git a/tests/unit/out/unsafe/foreach_mut.rs b/tests/unit/out/unsafe/foreach_mut.rs index 41053eae..d3f3b73e 100644 --- a/tests/unit/out/unsafe/foreach_mut.rs +++ b/tests/unit/out/unsafe/foreach_mut.rs @@ -27,7 +27,7 @@ unsafe fn main_0() -> i32 { } 'loop_: for x in 0..(v1.len()) { let mut x = v1.as_mut_ptr().add(x); - (*x) = (((*x) as i32) + 10) as i32; + (*x) += 10; } 'loop_: for x in 0..(v1.len()) { let mut x = v1.as_ptr().add(x); @@ -47,7 +47,7 @@ unsafe fn main_0() -> i32 { } 'loop_: for p in 0..(v2.len()) { let mut p = v2[p].clone(); - (*p) = (((*p) as i32) + 5) as i32; + (*p) += 5; } 'loop_: for p in 0..(v2.len()) { let mut p = v2[p].clone(); diff --git a/tests/unit/out/unsafe/unique_ptr_deref_ops.rs b/tests/unit/out/unsafe/unique_ptr_deref_ops.rs index 295ac211..164ee079 100644 --- a/tests/unit/out/unsafe/unique_ptr_deref_ops.rs +++ b/tests/unit/out/unsafe/unique_ptr_deref_ops.rs @@ -13,9 +13,9 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut p: Option> = Some(Box::new(10)); - (*p.as_deref_mut().unwrap()) = (((*p.as_deref_mut().unwrap()) as i32) + 5) as i32; - (*p.as_deref_mut().unwrap()) = (((*p.as_deref_mut().unwrap()) as i32) - 3) as i32; - (*p.as_deref_mut().unwrap()) = (((*p.as_deref_mut().unwrap()) as i32) * 2) as i32; + (*p.as_deref_mut().unwrap()) += 5; + (*p.as_deref_mut().unwrap()) -= 3; + (*p.as_deref_mut().unwrap()) *= 2; let mut q: Option> = Some(Box::new(1)); let mut sum: i32 = ((*p.as_deref_mut().unwrap()) + (*q.as_deref_mut().unwrap())); return sum;