diff --git a/cpp2rust/converter/rules/expr_matcher.cpp b/cpp2rust/converter/rules/expr_matcher.cpp index e244c861c..c08fed92c 100644 --- a/cpp2rust/converter/rules/expr_matcher.cpp +++ b/cpp2rust/converter/rules/expr_matcher.cpp @@ -143,7 +143,8 @@ clang::Expr *getObject(clang::ASTContext &ctx, clang::Expr *object) { } std::vector getOperands(clang::ASTContext &ctx, - const clang::Expr *use) { + const clang::Expr *use, + unsigned arity = 0) { auto expr = const_cast(RuleDecls::SkipImplicit(use)); while (auto cast = llvm::dyn_cast(expr)) { expr = @@ -182,7 +183,7 @@ std::vector getOperands(clang::ASTContext &ctx, ->IgnoreParenImpCasts(); operands.push_back(getObject(ctx, base)); } - while (!operands.empty() && + while (operands.size() > arity && llvm::isa(operands.back())) { operands.pop_back(); } @@ -298,7 +299,7 @@ void checkCallable(clang::Sema &sema, const clang::Expr *use, } RuleDecls::Trial trial(sema); auto loc = use->getBeginLoc(); - auto operands = getOperands(sema.Context, use); + auto operands = getOperands(sema.Context, use, rule->getNumParams()); clang::OverloadCandidateSet set(loc, clang::OverloadCandidateSet::CSK_Normal); auto found = clang::DeclAccessPair::make(rule, clang::AS_public); if (auto tmpl = rule->getDescribedFunctionTemplate()) { @@ -347,7 +348,8 @@ MatchResult matchTemplate(clang::Sema &sema, const clang::Expr *use, auto &ctx = sema.Context; auto explicit_args = getResultArgs(sema, rule, use); auto specialization = - deduce(sema, rule, explicit_args, getOperands(ctx, use)); + deduce(sema, rule, explicit_args, + getOperands(ctx, use, rule->getTemplatedDecl()->getNumParams())); if (!specialization) { return std::nullopt; } diff --git a/rules/string/src.cpp b/rules/string/src.cpp index a17d32bdb..9e0b4f618 100644 --- a/rules/string/src.cpp +++ b/rules/string/src.cpp @@ -83,3 +83,7 @@ std::string &f29(std::string &dst, const std::string &src) { return dst = src; } std::string &f30(std::string &dst, std::string &&src) { return dst = std::move(src); } + +std::size_t f32(const std::string &a0, const char *a1, std::size_t a2) { + return a0.find(a1, a2); +} diff --git a/rules/string/tgt_refcount.rs b/rules/string/tgt_refcount.rs index 64e2350f0..9f2e447cd 100644 --- a/rules/string/tgt_refcount.rs +++ b/rules/string/tgt_refcount.rs @@ -202,3 +202,12 @@ fn f30(a0: Ptr>, a1: &mut Vec) { fn f31(a0: Vec, a1: Ptr) -> bool { a1.with_c_str(|__s| a0[..a0.len().saturating_sub(1)] != *__s) } + +fn f32(a0: Vec, a1: Ptr, a2: usize) -> usize { + let __hay = &a0[..a0.len().saturating_sub(1)]; + a1.with_c_str(|__needle| { + (a2..=__hay.len().saturating_sub(__needle.len())) + .find(|&__i| __hay[__i..].starts_with(__needle)) + .unwrap_or(usize::MAX) + }) +} diff --git a/rules/string/tgt_unsafe.rs b/rules/string/tgt_unsafe.rs index 958a74029..388fb3859 100644 --- a/rules/string/tgt_unsafe.rs +++ b/rules/string/tgt_unsafe.rs @@ -202,3 +202,11 @@ unsafe fn f31(a0: Vec, a1: *const libc::c_char) -> bool { std::slice::from_raw_parts(s, (0..).take_while(|&i| *s.add(i) != 0).count() + 1).to_vec() } } + +unsafe fn f32(a0: Vec, a1: *const libc::c_char, a2: usize) -> usize { + let __hay = &a0[..a0.len() - 1]; + let __needle = ::std::slice::from_raw_parts(a1, libc::strlen(a1)); + (a2..=__hay.len().saturating_sub(__needle.len())) + .find(|&__i| __hay[__i..].starts_with(__needle)) + .unwrap_or(usize::MAX) +} diff --git a/tests/unit/out/refcount/string.rs b/tests/unit/out/refcount/string.rs index dd9392010..aa4671d31 100644 --- a/tests/unit/out/refcount/string.rs +++ b/tests/unit/out/refcount/string.rs @@ -292,6 +292,33 @@ fn main_0() -> i32 { .unwrap_or(usize::MAX) }); assert!((pos == ((-1_i64 as u64) as usize))); + pos = { + let __hay = &result[..result.len().saturating_sub(1)]; + Ptr::::from_string_literal(b"f").with_c_str(|__needle| { + (0_usize..=__hay.len().saturating_sub(__needle.len())) + .find(|&__i| __hay[__i..].starts_with(__needle)) + .unwrap_or(usize::MAX) + }) + }; + assert!((pos == 5_usize)); + pos = { + let __hay = &result[..result.len().saturating_sub(1)]; + Ptr::::from_string_literal(b"oo").with_c_str(|__needle| { + (0_usize..=__hay.len().saturating_sub(__needle.len())) + .find(|&__i| __hay[__i..].starts_with(__needle)) + .unwrap_or(usize::MAX) + }) + }; + assert!((pos == 6_usize)); + pos = { + let __hay = &result[..result.len().saturating_sub(1)]; + Ptr::::from_string_literal(b"x").with_c_str(|__needle| { + (0_usize..=__hay.len().saturating_sub(__needle.len())) + .find(|&__i| __hay[__i..].starts_with(__needle)) + .unwrap_or(usize::MAX) + }) + }; + assert!((pos == ((-1_i64 as u64) as usize))); let string_to_cast: Value> = Rc::new(RefCell::new({ let mut __bytes = Ptr::::from_string_literal(b"cast").to_c_bytes(); __bytes.push(0); diff --git a/tests/unit/out/unsafe/string.rs b/tests/unit/out/unsafe/string.rs index eb2fe255e..fa864e979 100644 --- a/tests/unit/out/unsafe/string.rs +++ b/tests/unit/out/unsafe/string.rs @@ -312,6 +312,30 @@ unsafe fn main_0() -> i32 { None => usize::MAX, }; assert!(((pos) == ((-1_i64 as u64) as usize))); + pos = { + let __hay = &result[..result.len() - 1]; + let __needle = ::std::slice::from_raw_parts(c"f".as_ptr(), libc::strlen(c"f".as_ptr())); + (0_usize..=__hay.len().saturating_sub(__needle.len())) + .find(|&__i| __hay[__i..].starts_with(__needle)) + .unwrap_or(usize::MAX) + }; + assert!(((pos) == (5_usize))); + pos = { + let __hay = &result[..result.len() - 1]; + let __needle = ::std::slice::from_raw_parts(c"oo".as_ptr(), libc::strlen(c"oo".as_ptr())); + (0_usize..=__hay.len().saturating_sub(__needle.len())) + .find(|&__i| __hay[__i..].starts_with(__needle)) + .unwrap_or(usize::MAX) + }; + assert!(((pos) == (6_usize))); + pos = { + let __hay = &result[..result.len() - 1]; + let __needle = ::std::slice::from_raw_parts(c"x".as_ptr(), libc::strlen(c"x".as_ptr())); + (0_usize..=__hay.len().saturating_sub(__needle.len())) + .find(|&__i| __hay[__i..].starts_with(__needle)) + .unwrap_or(usize::MAX) + }; + assert!(((pos) == ((-1_i64 as u64) as usize))); let mut string_to_cast: Vec = { let s = c"cast".as_ptr(); std::slice::from_raw_parts(s, (0..).take_while(|&i| *s.add(i) != 0).count() + 1).to_vec() diff --git a/tests/unit/string.cpp b/tests/unit/string.cpp index 41ba4d0ee..302875e95 100644 --- a/tests/unit/string.cpp +++ b/tests/unit/string.cpp @@ -125,6 +125,12 @@ int main() { assert(pos == 7); pos = result.find_last_of("x"); assert(pos == -1ul); + pos = result.find("f"); + assert(pos == 5); + pos = result.find("oo"); + assert(pos == 6); + pos = result.find("x"); + assert(pos == -1ul); std::string string_to_cast = "cast"; [[maybe_unused]] std::uint8_t *output_data = reinterpret_cast(&string_to_cast[0]);