Skip to content

Commit 8b800d7

Browse files
committed
Detect double borrow error in va_arg usages
1 parent f91e7e4 commit 8b800d7

1 file changed

Lines changed: 20 additions & 3 deletions

File tree

cpp2rust/converter/models/converter_refcount.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,18 @@ void ConverterRefCount::ConvertVarInit(clang::QualType qual_type,
14951495
in_function_formals_ = false;
14961496
}
14971497

1498+
static bool ContainsVAArgExpr(const clang::Stmt *stmt) {
1499+
if (clang::isa<clang::VAArgExpr>(stmt)) {
1500+
return true;
1501+
}
1502+
for (auto *child : stmt->children()) {
1503+
if (ContainsVAArgExpr(child)) {
1504+
return true;
1505+
}
1506+
}
1507+
return false;
1508+
}
1509+
14981510
static std::unordered_set<const clang::ValueDecl *>
14991511
GetAllVars(const clang::Stmt *stmt) {
15001512
std::unordered_set<const clang::ValueDecl *> vars;
@@ -1606,9 +1618,14 @@ void ConverterRefCount::ConvertGenericBinaryOperator(
16061618
auto sides_contain_ptr_or_deref = std::ranges::any_of(rhs_vars, predicate) ||
16071619
std::ranges::any_of(lhs_vars, predicate);
16081620

1609-
auto may_cause_borrow_mut_err = !sides_contains_literal &&
1610-
!same_var_on_both_sides &&
1611-
sides_contain_ptr_or_deref;
1621+
auto both_sides_have_va_arg = same_var_on_both_sides &&
1622+
ContainsVAArgExpr(lhs) &&
1623+
ContainsVAArgExpr(rhs);
1624+
1625+
auto may_cause_borrow_mut_err =
1626+
both_sides_have_va_arg ||
1627+
(!sides_contains_literal && !same_var_on_both_sides &&
1628+
sides_contain_ptr_or_deref);
16121629

16131630
if (may_cause_borrow_mut_err) {
16141631
StrCat(std::format("{{ let _lhs = {}; _lhs {} {} }}",

0 commit comments

Comments
 (0)