diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 055db2e8f..e57ce6dc5 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1840,11 +1840,16 @@ bool Converter::ConvertSpecialCall(clang::CallExpr *expr) { return false; } +bool Converter::ExprMapsValueToPointer(const clang::CallExpr *expr) const { + return Mapper::Contains(ctx_, expr) && !expr->getType()->isPointerType() && + RuleRegistry::MapsToPointer(ctx_, expr->getType()); +} + void Converter::EmitCallResult(clang::CallExpr *expr, std::string str, const TempMaterializationCtx *temps) { bool deref = (GetReturnTypeOfFunction(expr)->isReferenceType() || (temps && IsReferenceType(expr))) && - !isAddrOf() && !isVoid(); + !isAddrOf() && !isVoid() && !ExprMapsValueToPointer(expr); // The dereference is in the block of the temporaries, so they are still // alive, as is the read of a field of the result. if (deref && !(temps && Mapper::IsRefExpr(ctx_, expr))) { diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index 65eae3dac..8e74dd489 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -899,6 +899,8 @@ class Converter : public clang::RecursiveASTVisitor { virtual bool IsReferenceType(const clang::Expr *expr) const; + bool ExprMapsValueToPointer(const clang::CallExpr *expr) const; + virtual bool RecordDerivesDefault(const clang::RecordDecl *decl); virtual bool TypeDerivesDefault(clang::QualType qual_type); diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 104f2d6fb..5cee2b16a 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1237,7 +1237,7 @@ void ConverterRefCount::EmitCallResult(clang::CallExpr *expr, std::string str, }; auto ty = GetReturnTypeOfFunction(expr); if (auto *ref = ty->getAs(); - ref && !isAddrOf() && !isVoid()) { + ref && !isAddrOf() && !isVoid() && !ExprMapsValueToPointer(expr)) { if (isLValue()) { pending_deref_.set(wrap(std::move(str)), /*fresh=*/true); return; diff --git a/rules/vector/tgt_refcount.rs b/rules/vector/tgt_refcount.rs index 2bb7fce9d..20ec5d24f 100644 --- a/rules/vector/tgt_refcount.rs +++ b/rules/vector/tgt_refcount.rs @@ -160,16 +160,19 @@ fn f118(a0: Ptr, a1: usize) -> Ptr { } fn f119(a0: Ptr, a1: bool) -> Ptr { - a0.write(a1); - a0 + let __a0 = a0; + __a0.write(a1); + __a0 } fn f120(a0: Ptr, a1: bool) -> Ptr { - a0.write(a1); - a0 + let __a0 = a0; + __a0.write(a1); + __a0 } fn f121(a0: Ptr, a1: Ptr) -> Ptr { - a0.write(a1.read()); - a0 + let __a0 = a0; + __a0.write(a1.read()); + __a0 } diff --git a/rules/vector/tgt_unsafe.rs b/rules/vector/tgt_unsafe.rs index 2b92694f4..b4e7b9a55 100644 --- a/rules/vector/tgt_unsafe.rs +++ b/rules/vector/tgt_unsafe.rs @@ -267,16 +267,19 @@ unsafe fn f118(a0: &mut Vec, a1: usize) -> *mut bool { } unsafe fn f119(a0: *mut bool, a1: bool) -> *mut bool { - *a0 = a1; - a0 + let __a0 = a0; + *__a0 = a1; + __a0 } unsafe fn f120(a0: *mut bool, a1: bool) -> *mut bool { - *a0 = a1; - a0 + let __a0 = a0; + *__a0 = a1; + __a0 } unsafe fn f121(a0: *mut bool, a1: *mut bool) -> *mut bool { - *a0 = *a1; - a0 + let __a0 = a0; + *__a0 = *a1; + __a0 } diff --git a/tests/unit/out/refcount/vector_bool_reference.rs b/tests/unit/out/refcount/vector_bool_reference.rs index 64a725f63..956a8d469 100644 --- a/tests/unit/out/refcount/vector_bool_reference.rs +++ b/tests/unit/out/refcount/vector_bool_reference.rs @@ -15,33 +15,33 @@ fn main_0() -> i32 { let mut r1: Ptr = v1.decay().offset(0_usize as isize); assert!((v1.decay().offset(0_usize as isize).read()) && (r1.read())); { - r1.write(false); - (r1).clone() + let __a0 = (r1).clone(); + __a0.write(false); + __a0 }; assert!(!(v1.decay().offset(0_usize as isize).read())); let it: Value> = Rc::new(RefCell::new(v1.decay().begin())); let mut r2: Ptr = (*it.borrow()).iter_deref(); { - r2.write(true); - (r2).clone() + let __a0 = (r2).clone(); + __a0.write(true); + __a0 }; assert!(v1.decay().offset(0_usize as isize).read()); { - v1.decay().offset(0_usize as isize).write(false); - v1.decay().offset(0_usize as isize) + let __a0 = v1.decay().offset(0_usize as isize); + __a0.write(false); + __a0 }; assert!(!(v1.decay().offset(0_usize as isize).read())); { let v: Value> = Rc::new(RefCell::new(Vec::from([false, false, false]))); let mut i: i32 = 0; - let mut b: bool = (*{ - v.decay() - .offset((i.postfix_inc() as usize) as isize) - .write(true); - v.decay().offset((i.postfix_inc() as usize) as isize) + let mut b: bool = { + let __a0 = v.decay().offset((i.postfix_inc() as usize) as isize); + __a0.write(true); + __a0 } - .upgrade() - .deref()) .read(); assert!(b); } diff --git a/tests/unit/out/unsafe/vector_bool_reference.rs b/tests/unit/out/unsafe/vector_bool_reference.rs index f06cd8555..8a0f769b1 100644 --- a/tests/unit/out/unsafe/vector_bool_reference.rs +++ b/tests/unit/out/unsafe/vector_bool_reference.rs @@ -17,29 +17,33 @@ unsafe fn main_0() -> i32 { let mut r1: *mut bool = (&mut (v1)[0_usize as usize] as *mut bool); assert!((*(&mut (v1)[0_usize as usize] as *mut bool)) && (*r1)); { - *r1 = false; - r1 + let __a0 = r1; + *__a0 = false; + __a0 }; assert!(!(*(&mut (v1)[0_usize as usize] as *mut bool))); let mut it: UnsafeRandomAccessIterator = v1.begin(); let mut r2: *mut bool = it.iter_deref(); { - *r2 = true; - r2 + let __a0 = r2; + *__a0 = true; + __a0 }; assert!(*(&mut (v1)[0_usize as usize] as *mut bool)); { - *(&mut (v1)[0_usize as usize] as *mut bool) = false; - (&mut (v1)[0_usize as usize] as *mut bool) + let __a0 = (&mut (v1)[0_usize as usize] as *mut bool); + *__a0 = false; + __a0 }; assert!(!(*(&mut (v1)[0_usize as usize] as *mut bool))); { let mut v: Vec = Vec::from([false, false, false]); let mut i: i32 = 0; - let mut b: bool = *(*{ - *(&mut (v)[(i.postfix_inc() as usize) as usize] as *mut bool) = true; - (&mut (v)[(i.postfix_inc() as usize) as usize] as *mut bool) - }); + let mut b: bool = *{ + let __a0 = (&mut (v)[(i.postfix_inc() as usize) as usize] as *mut bool); + *__a0 = true; + __a0 + }; assert!(b); } return 0; diff --git a/tests/unit/vector_bool_reference.cpp b/tests/unit/vector_bool_reference.cpp index 9d5ff59f2..04c00eb01 100644 --- a/tests/unit/vector_bool_reference.cpp +++ b/tests/unit/vector_bool_reference.cpp @@ -1,4 +1,3 @@ -// XFAIL: refcount, unsafe #include #include @@ -14,11 +13,11 @@ int main() { assert(v1[0]); v1[0] = false; assert(!v1[0]); -{ - std::vector v = {false, false, false }; - int i = 0; - bool b = v[i++] = true; - assert(b); -} + { + std::vector v = {false, false, false}; + int i = 0; + bool b = v[i++] = true; + assert(b); + } return 0; }