From c88391f5ef1596782ed345583b6988789bf59149 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 16 May 2026 14:12:56 +0100 Subject: [PATCH 1/2] Distinguish between empty match and non-match --- cpp2rust/converter/mapper.cpp | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index a0c5ae8c..d4196db8 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -93,7 +94,7 @@ void AddTypeRule(std::string src, TranslationRule::TypeRule &&rule) { // template_str = "std::vector::vector()" // instantiated = "std::vector::vector()" // result = { "int" } -std::optional> +std::optional>> matchTemplate(const std::string &template_str, const std::string &instantiated) { auto matchLiteralAt = [&](const std::string &input_str, size_t pos, @@ -220,7 +221,7 @@ matchTemplate(const std::string &template_str, return std::string::npos; }; - std::vector captured; + std::vector> captured; size_t ti = 0; size_t si = 0; @@ -250,9 +251,9 @@ matchTemplate(const std::string &template_str, captured.resize(std::max(captured.size(), type_idx + 1)); auto &repl = captured[type_idx]; - if (!repl.empty()) { + if (repl.has_value()) { size_t end_pos = 0; - if (!matchLiteralAt(instantiated, si, repl, end_pos)) { + if (!matchLiteralAt(instantiated, si, *repl, end_pos)) { return std::nullopt; } si = end_pos; @@ -338,7 +339,7 @@ matchTemplate(const std::string &template_str, // types = { {"i32"} } // tgt_template = "Vec" // result = "Vec" -std::string instantiateTgt(const std::vector &types, +std::string instantiateTgt(const std::vector> &types, const std::string &tgt_template) { assert(types.size() <= 9); std::string instantiated_template = tgt_template; @@ -351,7 +352,7 @@ std::string instantiateTgt(const std::vector &types, ++pos; continue; } - auto &repl = types.at(instantiated_template[pos + 1] - '1'); + const auto &repl = types.at(instantiated_template[pos + 1] - '1').value(); instantiated_template.replace(pos, 2, repl); pos += repl.length(); } @@ -359,12 +360,12 @@ std::string instantiateTgt(const std::vector &types, } template -std::pair> +std::pair>> search(std::unordered_multimap &map, const std::string &txt, const std::string &key) { auto [it, end] = map.equal_range(key); T *rule = nullptr; - std::vector subs; + std::vector> subs; for (; it != end; ++it) { auto &this_rule = it->second; @@ -540,7 +541,9 @@ std::string mapTypeStringRecursive(const std::string &cpp_type) { assert(0 && "Type is not present in types_"); } for (auto &ty : subs) { - ty = mapTypeStringRecursive(ty); + if (ty) { + ty = mapTypeStringRecursive(*ty); + } } return instantiateTgt(subs, rule->type_info.type); } @@ -608,7 +611,9 @@ std::string InstantiateTemplate(const clang::Expr *expr, unsigned n) { return text; } for (auto &ty : subs) { - ty = mapTypeStringRecursive(ty); + if (ty) { + ty = mapTypeStringRecursive(*ty); + } } return instantiateTgt(subs, text); } @@ -618,7 +623,9 @@ std::string Map(clang::QualType qual_type) { auto [rule, subs] = search(types_, type_str, GetTypeMapKey(type_str)); if (rule) { for (auto &ty : subs) { - ty = mapTypeStringRecursive(ty); + if (ty) { + ty = mapTypeStringRecursive(*ty); + } } return instantiateTgt(subs, rule->type_info.type); } @@ -651,7 +658,9 @@ std::string GetParamType(const clang::Expr *expr, unsigned index) { auto expr_str = ToString(expr); auto [rule, subs] = search(exprs_, expr_str, GetExprMapKey(expr_str)); for (auto &ty : subs) { - ty = mapTypeStringRecursive(ty); + if (ty) { + ty = mapTypeStringRecursive(*ty); + } } return instantiateTgt(subs, rule->params.at(index).type); } From 37f49b8326748eb630ff11d11de3124cf7e29f98 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 16 May 2026 14:13:18 +0100 Subject: [PATCH 2/2] Add addrof back test --- .../unit/out/refcount/vector_addr_of_back.rs | 23 +++++++++++++++++++ tests/unit/out/unsafe/vector_addr_of_back.rs | 21 +++++++++++++++++ tests/unit/vector_addr_of_back.cpp | 11 +++++++++ 3 files changed, 55 insertions(+) create mode 100644 tests/unit/out/refcount/vector_addr_of_back.rs create mode 100644 tests/unit/out/unsafe/vector_addr_of_back.rs create mode 100644 tests/unit/vector_addr_of_back.cpp diff --git a/tests/unit/out/refcount/vector_addr_of_back.rs b/tests/unit/out/refcount/vector_addr_of_back.rs new file mode 100644 index 00000000..0c180c54 --- /dev/null +++ b/tests/unit/out/refcount/vector_addr_of_back.rs @@ -0,0 +1,23 @@ +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 outer: Value>>> = Rc::new(RefCell::new(Vec::new())); + let inner: Value> = Rc::new(RefCell::new(Vec::new())); + (outer.as_pointer() as Ptr>>>).with_mut(|__v: &mut Vec>>| { + __v.push(Rc::new(RefCell::new((*inner.borrow()).clone()))) + }); + let sink: Value>> = Rc::new(RefCell::new( + ((*outer.borrow())[(*outer.borrow()).len() - 1].as_pointer()), + )); + assert!(((*(*sink.borrow()).upgrade().deref()).len() as u64 == 0_u64)); + return 0; +} diff --git a/tests/unit/out/unsafe/vector_addr_of_back.rs b/tests/unit/out/unsafe/vector_addr_of_back.rs new file mode 100644 index 00000000..4939d073 --- /dev/null +++ b/tests/unit/out/unsafe/vector_addr_of_back.rs @@ -0,0 +1,21 @@ +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 outer: Vec> = Vec::new(); + let mut inner: Vec = Vec::new(); + outer.push(inner.clone()); + let mut sink: *mut Vec = ((outer).last_mut().unwrap()); + assert!((((*sink.cast_const()).len() as u64) == (0_u64))); + return 0; +} diff --git a/tests/unit/vector_addr_of_back.cpp b/tests/unit/vector_addr_of_back.cpp new file mode 100644 index 00000000..9212fe75 --- /dev/null +++ b/tests/unit/vector_addr_of_back.cpp @@ -0,0 +1,11 @@ +#include +#include + +int main() { + std::vector> outer; + std::vector inner; + outer.push_back(inner); + auto *sink = &outer.back(); + assert(sink->size() == 0); + return 0; +}