Skip to content

Commit 392a53c

Browse files
committed
Materialize temporary when calling method
1 parent 9c84c0a commit 392a53c

4 files changed

Lines changed: 25 additions & 9 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2669,11 +2669,8 @@ void Converter::ConvertGenericBinaryOperator(clang::BinaryOperator *expr) {
26692669
}
26702670

26712671
bool Converter::IsReferenceType(const clang::Expr *expr) const {
2672-
const auto *e = expr->IgnoreCasts();
2672+
const auto *e = IgnoreStdMove(expr->IgnoreCasts())->IgnoreCasts();
26732673
if (const auto *call = clang::dyn_cast<clang::CallExpr>(e)) {
2674-
if (call->isCallToStdMove()) {
2675-
return IsReferenceType(call->getArg(0));
2676-
}
26772674
return !clang::isa<clang::CXXOperatorCallExpr>(call) &&
26782675
GetReturnTypeOfFunction(call)->isReferenceType();
26792676
}

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,25 @@ bool IsBuiltinVaCopy(const clang::CallExpr *expr) {
13471347
return false;
13481348
}
13491349

1350+
const clang::Expr *IgnoreStdMove(const clang::Expr *expr) {
1351+
while (true) {
1352+
const auto *call =
1353+
clang::dyn_cast<clang::CallExpr>(expr->IgnoreParenImpCasts());
1354+
if (!call || !call->isCallToStdMove()) {
1355+
return expr;
1356+
}
1357+
expr = call->getArg(0);
1358+
}
1359+
}
1360+
1361+
bool IsTemporaryObject(const clang::Expr *expr) {
1362+
const auto *operand = IgnoreStdMove(expr);
1363+
if (operand != expr) {
1364+
return !operand->isGLValue();
1365+
}
1366+
return !expr->isLValue();
1367+
}
1368+
13501369
bool ContainsVAArgExpr(const clang::Stmt *stmt) {
13511370
if (clang::isa<clang::VAArgExpr>(stmt)) {
13521371
return true;

‎cpp2rust/converter/converter_lib.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ bool IsBuiltinVaEnd(const clang::CallExpr *expr);
243243

244244
bool IsBuiltinVaCopy(const clang::CallExpr *expr);
245245

246+
const clang::Expr *IgnoreStdMove(const clang::Expr *expr);
247+
248+
bool IsTemporaryObject(const clang::Expr *expr);
249+
246250
bool ContainsVAArgExpr(const clang::Stmt *stmt);
247251

248252
clang::Expr *NormalizeToBool(clang::Expr *expr, clang::ASTContext &ctx);

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2658,11 +2658,7 @@ void ConverterRefCount::SetUFCSReceiver(clang::Expr *base, bool is_arrow,
26582658
}
26592659
return;
26602660
}
2661-
auto *moved = clang::dyn_cast<clang::CallExpr>(base->IgnoreParenImpCasts());
2662-
bool is_moved_object =
2663-
moved && moved->isCallToStdMove() && moved->getArg(0)->isGLValue();
2664-
if (!base->isLValue() && !is_moved_object &&
2665-
base->getType()->isRecordType() &&
2661+
if (IsTemporaryObject(base) && base->getType()->isRecordType() &&
26662662
!IsReferenceType(base->IgnoreImplicit())) {
26672663
PushConversionKind push(*this, ConversionKind::FullRefCount);
26682664
ufcs_receiver_ =

0 commit comments

Comments
 (0)