diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index 6be40f17..20115912 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -40,6 +40,7 @@ clang::PrintingPolicy getPrintPolicy() { policy.SuppressScope = false; policy.FullyQualifiedName = true; policy.SuppressUnwrittenScope = true; + policy.UsePreferredNames = true; return policy; } diff --git a/cpp2rust/cpp_rule_preprocessor.cpp b/cpp2rust/cpp_rule_preprocessor.cpp index 48185130..463b7423 100644 --- a/cpp2rust/cpp_rule_preprocessor.cpp +++ b/cpp2rust/cpp_rule_preprocessor.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT license that can be found in the LICENSE file. #include +#include #include #include #include @@ -58,10 +59,15 @@ struct LookupInfo { name = dm->getMember(); kind = LookupKind::CXXMethodName; explicitArgs = dm->template_arguments(); + } else if (const auto *um = + llvm::dyn_cast(expr)) { + name = um->getMemberName(); + kind = LookupKind::CXXMethodName; + explicitArgs = um->template_arguments(); } else if (const auto *dref = llvm::dyn_cast(expr)) { clang::DeclarationName dname = dref->getDeclName(); - if (name.getNameKind() == + if (dname.getNameKind() == clang::DeclarationName::NameKind::CXXConstructorName) { name = dname; kind = LookupKind::CXXConstructorName; @@ -260,7 +266,8 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback { return spec; } - if (result == clang::TemplateDeductionResult::SubstitutionFailure) { + if (result == clang::TemplateDeductionResult::SubstitutionFailure || + result == clang::TemplateDeductionResult::ConstraintsNotSatisfied) { if (const auto *deduced = info.takeCanonical()) { clang::TemplateArgumentListInfo targsInfo; for (const auto &arg : deduced->asArray()) { @@ -293,7 +300,9 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback { return ns; } - clang::RecordDecl *createRecordDecl(llvm::StringRef name) { + clang::RecordDecl * + createRecordDecl(llvm::StringRef name, + clang::QualType base = clang::QualType()) { bool owned = true; bool dependent = false; clang::CXXScopeSpec scope; @@ -306,11 +315,183 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback { clang::TypeResult(), false, false, clang::OffsetOfKind::Outside); assert(decl.isUsable() && "Record decl creation failed"); auto *rdecl = decl.getAs(); + rdecl->startDefinition(); + if (!base.isNull()) { + clang::CXXBaseSpecifier baseSpec( + clang::SourceRange(loc_, loc_), false, true, clang::AS_public, + sema_->Context.getTrivialTypeSourceInfo(base, loc_), + /*EllipsisLoc=*/clang::SourceLocation()); + const clang::CXXBaseSpecifier *bases[] = {&baseSpec}; + llvm::cast(rdecl)->setBases(bases, 1); + } rdecl->completeDefinition(); return rdecl; } + static clang::QualType getNTTPType(const clang::TemplateArgument &arg) { + switch (arg.getKind()) { + case clang::TemplateArgument::Integral: + return arg.getIntegralType(); + case clang::TemplateArgument::Declaration: + return arg.getParamTypeForDecl(); + case clang::TemplateArgument::NullPtr: + return arg.getNullPtrType(); + case clang::TemplateArgument::StructuralValue: + return arg.getStructuralValueType(); + default: + return clang::QualType(); + } + } + + clang::QualType + getTemplateIdType(clang::ClassTemplateDecl *decl, + llvm::ArrayRef args) { + clang::TemplateArgumentListInfo info(loc_, loc_); + for (const clang::TemplateArgument &arg : args) { + info.addArgument( + sema_->getTrivialTemplateArgumentLoc(arg, getNTTPType(arg), loc_)); + } + return sema_->CheckTemplateIdType(clang::ElaboratedTypeKeyword::None, + clang::TemplateName(decl), loc_, info, + sema_->getCurScope(), + /*ForNestedNameSpecifier=*/false); + } + + using MirrorMap = llvm::SmallDenseMap; + + clang::TypeSourceInfo *findMatch(MirrorMap &substs, clang::QualType type) { + const auto *tst = type->getAs(); + if (!tst) { + return nullptr; + } + + const auto *tdecl = llvm::dyn_cast_or_null( + tst->getTemplateName().getAsTemplateDecl()); + if (!tdecl) { + return nullptr; + } + + if (auto it = substs.find(tdecl->getCanonicalDecl()); it != substs.end()) { + auto match = getTemplateIdType(it->second, tst->template_arguments()); + assert(!match.isNull()); + return sema_->Context.getTrivialTypeSourceInfo(match, loc_); + } + return nullptr; + } + + clang::ClassTemplateDecl * + createInheritingTemplate(llvm::StringRef name, clang::ClassTemplateDecl *decl, + MirrorMap &substs) { + clang::ASTContext &ctx = sema_->Context; + auto *pattern = clang::CXXRecordDecl::Create( + ctx, clang::TagTypeKind::Struct, sema_->CurContext, loc_, loc_, + &ctx.Idents.get(name)); + + auto *mirror = clang::ClassTemplateDecl::Create( + ctx, sema_->CurContext, loc_, + clang::DeclarationName(&ctx.Idents.get(name)), + decl->getTemplateParameters(), pattern); + pattern->setDescribedClassTemplate(mirror); + mirror->setAccess(clang::AS_public); + substs.try_emplace(decl->getCanonicalDecl(), mirror); + + clang::QualType base_t = getTemplateIdType( + decl, decl->getTemplateParameters()->getInjectedTemplateArgs(ctx)); + assert(!base_t.isNull() && "Failed building mirror base"); + + pattern->startDefinition(); + clang::CXXBaseSpecifier base(clang::SourceRange(loc_, loc_), false, true, + clang::AS_public, + ctx.getTrivialTypeSourceInfo(base_t, loc_), + /*EllipsisLoc=*/clang::SourceLocation()); + const clang::CXXBaseSpecifier *bases[] = {&base}; + pattern->setBases(bases, 1); + + for (auto *member : decl->getTemplatedDecl()->decls()) { + if (const auto *td = llvm::dyn_cast(member)) { + if (auto *replacement = findMatch(substs, td->getUnderlyingType())) { + auto *copy = clang::TypedefDecl::Create( + ctx, pattern, loc_, loc_, td->getIdentifier(), replacement); + copy->setAccess(clang::AS_public); + pattern->addDecl(copy); + } + } else if (auto *tdecl = + llvm::dyn_cast(member)) { + clang::Sema::ContextRAII savedContext(*sema_, pattern); + createInheritingTemplate(tdecl->getName(), tdecl, substs); + } + } + + pattern->completeDefinition(); + sema_->CurContext->addDecl(mirror); + return mirror; + } + + clang::QualType createMirrorType(llvm::StringRef name, clang::QualType hint) { + clang::ASTContext &ctx = sema_->Context; + forceCompleteDefinition(hint); + + const auto *hdecl = hint->getAsCXXRecordDecl(); + assert(hdecl && "Failed resolving hint record declaration"); + assert(hdecl->isCompleteDefinition() && "Incomplete hint"); + + const auto *hspec = + llvm::dyn_cast(hdecl); + if (!hspec) { + // if it is not a template specialization inheriting from it suffices + clang::RecordDecl *rdecl = createRecordDecl(name, hint); + return ctx.getTagType(clang::ElaboratedTypeKeyword::None, + rdecl->getQualifier(), rdecl, false); + } + + MirrorMap substs; + auto *mirror = + createInheritingTemplate(name, hspec->getSpecializedTemplate(), substs); + clang::QualType spec = + getTemplateIdType(mirror, hspec->getTemplateArgs().asArray()); + assert(!spec.isNull() && spec->getAsCXXRecordDecl()); + + // required to print Tn instead of Tn + clang::NamespaceDecl *ns = createNamespaceDecl(); + auto *alias = + clang::TypeAliasDecl::Create(ctx, ns, loc_, loc_, &ctx.Idents.get(name), + ctx.getTrivialTypeSourceInfo(spec, loc_)); + ns->addDecl(alias); + + clang::QualType alias_t = ctx.getTypedefType( + clang::ElaboratedTypeKeyword::None, std::nullopt, alias); + spec->getAsCXXRecordDecl()->addAttr( + clang::PreferredNameAttr::CreateImplicit( + ctx, ctx.getTrivialTypeSourceInfo(alias_t, loc_))); + + return ctx.getCanonicalType(spec); + } + + clang::QualType + getDefaultArg(clang::TemplateDecl *decl, + const clang::TemplateTypeParmDecl *parm, + llvm::ArrayRef currentArgs) { + clang::QualType type = parm->getDefaultArgument().getArgument().getAsType(); + if (!type->isDependentType()) { + return type; + } + + clang::Sema::InstantiatingTemplate Inst(*sema_, loc_, decl); + assert(!Inst.isInvalid() && "Invalid instantiation context"); + + clang::MultiLevelTemplateArgumentList mtal; + mtal.setKind(clang::TemplateSubstitutionKind::Rewrite); + mtal.addOuterTemplateArguments(currentArgs); + + clang::TypeSourceInfo *tsi = + sema_->SubstType(sema_->Context.getTrivialTypeSourceInfo(type), mtal, + loc_, clang::DeclarationName()); + assert(tsi && "Template argument type instantiation failed"); + return tsi->getType(); + } + clang::VarDecl *createVarDecl(clang::QualType type, llvm::StringRef name, clang::StorageClass sclass = clang::SC_None) { clang::ASTContext &ctx = sema_->Context; @@ -355,11 +536,19 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback { createTemplateArguments(clang::TemplateDecl *decl, llvm::SmallVectorImpl &out) { for (clang::NamedDecl *param : *decl->getTemplateParameters()) { - if (llvm::isa(param)) { - clang::RecordDecl *rdecl = createRecordDecl(param->getName()); - clang::QualType type = - sema_->Context.getTagType(clang::ElaboratedTypeKeyword::None, - rdecl->getQualifier(), rdecl, false); + if (const auto *ttp = + llvm::dyn_cast(param)) { + clang::QualType type; + if (ttp->hasDefaultArgument()) { + clang::QualType hint = getDefaultArg(decl, ttp, out); + assert(!hint.isNull() && "Failed retrieving type hint"); + type = createMirrorType(param->getName(), hint); + } else { + clang::RecordDecl *rdecl = createRecordDecl(param->getName()); + type = sema_->Context.getTagType(clang::ElaboratedTypeKeyword::None, + rdecl->getQualifier(), rdecl, false); + } + assert(!type.isNull() && "Template type argument creation failed"); out.emplace_back(type); } else if (const auto *nttp = llvm::dyn_cast(param)) { @@ -505,6 +694,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback { clang::NamespaceDecl *ns = createNamespaceDecl(); clang::Sema::ContextRAII savedContext(*sema_, ns); clang::FunctionDecl *rule = instantiateRuleDecl(decl); + assert(rule && "Rule instantiation failed"); llvm::ArrayRef parms = rule->parameters(); auto csk = lookup.name.getNameKind() == clang::DeclarationName::NameKind::CXXOperatorName @@ -611,6 +801,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback { clang::NamespaceDecl *ns = createNamespaceDecl(); clang::Sema::ContextRAII savedContext(*sema_, ns); clang::FunctionDecl *rule = instantiateRuleDecl(decl); + assert(rule && "Rule instantiation failed"); clang::CXXRecordDecl *rdecl = resolveCXXRecordDecl(rule->getParamDecl(0)->getType()); assert(rdecl && "Failed fetching record decl"); @@ -628,6 +819,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback { clang::NamespaceDecl *ns = createNamespaceDecl(); clang::Sema::ContextRAII savedContext(*sema_, ns); clang::FunctionDecl *rule = instantiateRuleDecl(decl); + assert(rule && "Rule instantiation failed"); clang::Expr *obj = createOpaqueValueExpr( rule->getParamDecl(0)->getType().getNonReferenceType()); diff --git a/rule-preprocessor/src/syntactic.rs b/rule-preprocessor/src/syntactic.rs index aa3d8871..e7a6b4d1 100644 --- a/rule-preprocessor/src/syntactic.rs +++ b/rule-preprocessor/src/syntactic.rs @@ -121,6 +121,10 @@ impl SyntacticAnalysis { let mut file_ir = FileIr::new(); for fn_item in source_file.syntax().descendants().filter_map(ast::Fn::cast) { + if !cfg_matches_host(&fn_item) { + continue; + } + let Some(name) = fn_item.name() else { continue }; let fn_name = name.text().to_string(); @@ -130,9 +134,6 @@ impl SyntacticAnalysis { RuleIr::Type(TypeIrBuilder::new(&fn_item).build()), ); } else if fn_name.starts_with('f') { - if !cfg_matches_host(&fn_item) { - continue; - } file_ir.insert( fn_name.clone(), RuleIr::Fn(FnIrBuilder::new(&fn_item).build(path)), diff --git a/rules/vector/src.cpp b/rules/vector/src.cpp index 59037ff9..2abb52cd 100644 --- a/rules/vector/src.cpp +++ b/rules/vector/src.cpp @@ -10,6 +10,16 @@ template using t2 = typename std::vector::iterator; template using t3 = std::vector>; template using t4 = typename std::vector::const_iterator; +template > +using t5 = std::vector; + +#if defined(__linux__) +template > +using t6 = typename std::vector::iterator; +template > +using t7 = typename std::vector::const_iterator; +#endif + template typename std::vector::iterator f1(std::vector &o, typename std::vector::const_iterator it) { @@ -171,8 +181,7 @@ std::vector f36(const std::initializer_list &a0) { return std::vector(a0); } -template -std::vector f37(T2 *first, T2 *last) { +template std::vector f37(T2 *first, T2 *last) { return std::vector(first, last); } @@ -260,3 +269,261 @@ std::vector &f58(std::vector &dst, const std::vector &src) { template void f59(std::vector &o) { return o.shrink_to_fit(); } + +template > +typename std::vector::iterator +f60(std::vector &o, typename std::vector::const_iterator it) { + return o.erase(it); +} + +template > +std::size_t f61(const std::vector &o) { + return o.size(); +} + +template > +bool f62(const std::vector &o) { + return o.empty(); +} + +template > +std::vector f63() { + return std::vector(); +} + +template > +void f64(std::vector &o) { + return o.pop_back(); +} + +template > +T1 *f65(std::vector &o) { + return o.data(); +} + +template > +T1 &f66(std::vector &o, std::size_t idx) { + return o.at(idx); +} + +template > +std::vector f67(std::size_t n) { + return std::vector(n); +} + +template > +T1 &f68(std::vector &o) { + return o.front(); +} + +template > +T1 &f69(std::vector &o) { + return o.back(); +} + +template > +std::size_t f70(const std::vector &o) { + return o.capacity(); +} + +template > +void f71(std::vector &o, std::size_t n) { + return o.reserve(n); +} + +template > +typename std::vector::iterator f72(std::vector &o) { + return o.begin(); +} + +template > +void f73(std::vector &o, T1 &&value) { + return o.push_back(std::move(value)); +} + +template > +void f74(std::vector &o, std::size_t n) { + return o.resize(n); +} + +template > +void f75(std::vector &o) { + return o.clear(); +} + +template > +typename std::vector::iterator f76(std::vector &o) { + return o.end(); +} + +template > +typename std::vector::iterator +f77(std::vector &o, typename std::vector::const_iterator it, + T1 &&value) { + return o.insert(it, std::move(value)); +} + +template > +std::vector f78(std::size_t n, const T1 &value) { + return std::vector(n, value); +} + +template > +typename std::vector::iterator +f79(std::vector &o, typename std::vector::const_iterator it, + const T1 &value) { + return o.insert(it, value); +} + +template > +void f80(std::vector &o, const T1 &value) { + return o.push_back(value); +} + +template > +typename std::vector::reference +f81(typename std::vector::iterator it) { + return it.operator*(); +} + +template > +typename std::vector::iterator +f82(const typename std::vector::iterator &it) { + return typename std::vector::iterator(it); +} + +template > +typename std::vector::const_iterator +f83(const typename std::vector::iterator &it) { + return typename std::vector::const_iterator(it); +} + +template > +typename std::vector::iterator +f84(typename std::vector::iterator it, std::size_t n) { + return it.operator+(n); +} + +template > +bool f85(const typename std::vector::iterator &it1, + const typename std::vector::iterator &it2) { + return operator!=(it1, it2); +} + +template > +bool f86(const typename std::vector::iterator &it1, + const typename std::vector::iterator &it2) { + return operator==(it1, it2); +} + +template > +typename std::vector::iterator +f87(typename std::vector::iterator a0, int a1) { + return a0.operator++(a1); +} + +template > +typename std::vector::iterator::difference_type +f88(const typename std::vector::iterator &it1, + const typename std::vector::iterator &it2) { + return operator-(it1, it2); +} + +template > +typename std::vector::iterator & +f89(typename std::vector::iterator &it) { + return it.operator++(); +} + +template > +std::vector f90(const T1 *first, const T1 *last) { + return std::vector(first, last); +} + +template > +std::vector f91(const std::initializer_list &a0) { + return std::vector(a0); +} + +template , typename T3> +std::vector f92(T3 *first, T3 *last) { + return std::vector(first, last); +} + +template > +const T1 *f93(const std::vector &o) { + return o.data(); +} + +template > +typename std::vector::const_iterator +f94(typename std::vector::const_iterator first, + typename std::vector::const_iterator last) { + return std::max_element(first, last); +} + +template > +typename std::vector::const_iterator f95(const std::vector &o) { + return o.begin(); +} + +template > +typename std::vector::const_iterator f96(const std::vector &o) { + return o.end(); +} + +template > +void f97(std::vector &o, std::vector &a0) { + return o.swap(a0); +} + +template > +const T1 &f98(const std::vector &o, std::size_t idx) { + return o.at(idx); +} + +template > +const T1 &f99(const std::vector &o) { + return o.back(); +} + +template > +void f100(std::vector> &o, + const std::vector &value) { + return o.push_back(value); +} + +template > +typename std::vector::iterator +f101(std::vector &o, typename std::vector::const_iterator pos, + const T1 *first, const T1 *last) { + return o.insert(pos, first, last); +} + +template > +void f102(std::vector &o, std::size_t n, + const typename std::vector::value_type &value) { + return o.resize(n, value); +} + +template > +std::vector &f103(std::vector &dst, std::vector &&src) { + return dst.operator=(std::move(src)); +} + +template > +typename std::vector::const_iterator +f104(const std::vector &o) { + return o.cend(); +} + +template > +std::vector &f105(std::vector &dst, + const std::vector &src) { + return dst.operator=(src); +} + +template > +void f106(std::vector &o) { + return o.shrink_to_fit(); +} diff --git a/rules/vector/tgt_refcount.rs b/rules/vector/tgt_refcount.rs index aa3f43e3..f2c9a615 100644 --- a/rules/vector/tgt_refcount.rs +++ b/rules/vector/tgt_refcount.rs @@ -17,6 +17,16 @@ fn t4() -> Ptr { Ptr::null() } +#[cfg(target_os = "linux")] +fn t6() -> Ptr { + Ptr::null() +} + +#[cfg(target_os = "linux")] +fn t7() -> Ptr { + Ptr::null() +} + fn f1(a0: Ptr>, a1: Ptr) -> Ptr { let idx = a1.get_offset(); a0.with_mut(|__v: &mut Vec| __v.remove(idx)); @@ -201,3 +211,151 @@ fn f57(a0: Ptr) -> Ptr { fn f58(a0: Ptr>, a1: Vec) { a0.write(a1.clone()) } + +fn f60(a0: Ptr>, a1: Ptr) -> Ptr { + let idx = a1.get_offset(); + a0.with_mut(|__v: &mut Vec| __v.remove(idx)); + a0.to_strong().as_pointer() as Ptr +} + +fn f65(a0: Ptr) -> Ptr { + a0 +} + +fn f66(a0: Ptr, a1: usize) -> Ptr { + a0.offset(a1 as isize) +} + +fn f68(a0: Ptr) -> Ptr { + a0 +} + +fn f69(a0: Ptr) -> Ptr { + a0.to_last() +} + +fn f72(a0: Ptr) -> Ptr { + a0 +} + +fn f76(a0: Ptr) -> Ptr { + a0.to_end() +} + +fn f77(a0: &mut Vec, a1: Ptr, a2: T1) -> Ptr { + let __off = a1.get_offset(); + a0.insert(__off, a2); + a1 +} + +fn f79(a0: &mut Vec, a1: Ptr, a2: T1) -> Ptr { + let __off = a1.get_offset(); + a0.insert(__off, a2); + a1 +} + +fn f81(a0: Ptr) -> Ptr { + a0 +} + +fn f82(a0: Ptr) -> Ptr { + a0.clone() +} + +fn f83(a0: Ptr) -> Ptr { + a0.clone() +} + +fn f84(a0: Ptr, a1: usize) -> Ptr { + a0.offset(a1 as isize) +} + +fn f85(a0: Ptr, a1: Ptr) -> bool { + a0 != a1 +} + +fn f86(a0: Ptr, a1: Ptr) -> bool { + a0 == a1 +} + +fn f87(a0: &mut Ptr) -> Ptr { + a0.postfix_inc() +} + +fn f88(a0: Ptr, a1: Ptr) -> isize { + ((a0.get_offset() as isize) - (a1.get_offset() as isize)) +} + +fn f89(a0: &mut Ptr) -> Ptr { + a0.prefix_inc() +} + +fn f90(a0: Ptr, a1: Ptr) -> Vec { + let __count = a1.get_offset() - a0.get_offset(); + PtrValueIter::new(&a0, __count).collect::>() +} + +fn f92, T2: Clone + ByteRepr>(a0: Ptr, a1: Ptr) -> Vec { + let __count = a1.get_offset() - a0.get_offset(); + PtrValueIter::new(&a0, __count) + .map(|item| T1::try_from(item).ok().unwrap()) + .collect::>() +} + +fn f93(a0: Ptr) -> Ptr { + a0 +} + +fn f94(a0: Ptr, a1: Ptr) -> Ptr { + let __count = a1.get_offset() - a0.get_offset(); + let max_index = PtrValueIter::new(&a0, __count) + .enumerate() + .max_by_key(|&(_, val)| val) + .map(|(idx, _)| idx) + .unwrap_or(0); + + a0 + max_index +} + +fn f95(a0: Ptr) -> Ptr { + a0 +} + +fn f96(a0: Ptr) -> Ptr { + a0.to_end() +} + +fn f98(a0: Ptr, a1: usize) -> Ptr { + a0.offset(a1 as isize) +} + +fn f99(a0: Ptr) -> Ptr { + a0.to_last() +} + +fn f101( + a0: Ptr>, + a1: Ptr, + a2: Ptr, + a3: Ptr, +) -> Ptr> { + let start_idx = a1.get_offset(); + let count = a3.get_offset() - a2.get_offset(); + let temp_vec: Vec = PtrValueIter::new(&a2, count).collect(); + a0.with_mut(|v: &mut Vec| { + v.splice(start_idx..start_idx, temp_vec); + }); + a0 + start_idx +} + +fn f103(a0: Ptr>, a1: &mut Vec) { + a0.write(std::mem::take(&mut *a1)) +} + +fn f104(a0: Ptr) -> Ptr { + a0.to_end() +} + +fn f105(a0: Ptr>, a1: Vec) { + a0.write(a1.clone()) +} diff --git a/rules/vector/tgt_unsafe.rs b/rules/vector/tgt_unsafe.rs index ecedc5c7..37866d27 100644 --- a/rules/vector/tgt_unsafe.rs +++ b/rules/vector/tgt_unsafe.rs @@ -19,6 +19,20 @@ fn t4() -> *const T1 { Default::default() } +fn t5() -> Vec { + Default::default() +} + +#[cfg(target_os = "linux")] +fn t6() -> *mut T1 { + Default::default() +} + +#[cfg(target_os = "linux")] +fn t7() -> *const T1 { + Default::default() +} + unsafe fn f1(a0: &mut Vec, a1: *const T1) -> *const T1 { let pos = a1.offset_from(a0.as_ptr()) as usize; a0.remove(pos); @@ -239,3 +253,223 @@ unsafe fn f58(a0: &mut Vec, a1: Vec) { unsafe fn f59(a0: &mut Vec) { a0.shrink_to_fit() } + +unsafe fn f60(a0: &mut Vec, a1: *const T1) -> *const T1 { + let pos = a1.offset_from(a0.as_ptr()) as usize; + a0.remove(pos); + a1 +} + +unsafe fn f61(a0: Vec) -> usize { + a0.len() +} + +unsafe fn f62(a0: Vec) -> bool { + a0.is_empty() +} + +unsafe fn f63() -> Vec { + Vec::new() +} + +unsafe fn f64(a0: &mut Vec) { + a0.pop(); +} + +unsafe fn f65(a0: &mut Vec) -> *mut T1 { + a0.as_mut_ptr() +} + +unsafe fn f66(a0: &mut Vec, a1: usize) -> *mut T1 { + &mut (a0)[a1 as usize] +} + +unsafe fn f67(a0: usize) -> Vec { + (0..(a0) as usize) + .map(|_| ::default()) + .collect::>() +} + +unsafe fn f68(a0: &mut Vec) -> *mut T1 { + ((a0).first_mut().unwrap()) +} + +unsafe fn f69(a0: &mut Vec) -> *mut T1 { + ((a0).last_mut().unwrap()) +} + +unsafe fn f70(a0: Vec) -> usize { + a0.capacity() +} + +unsafe fn f71(a0: &mut Vec, a1: usize) { + if a1 as usize > a0.capacity() as usize { + let len_0 = a0.len(); + a0.reserve_exact(a1 as usize - len_0 as usize); + } +} + +unsafe fn f72(a0: &mut Vec) -> *mut T1 { + a0.as_mut_ptr() +} + +unsafe fn f73(a0: &mut Vec, a1: &mut T1) { + a0.push(std::mem::take(&mut *a1)) +} + +unsafe fn f74(a0: &mut Vec, a1: usize) { + let __a0 = a1 as usize; + a0.resize_with(__a0, || ::default()) +} + +unsafe fn f75(a0: &mut Vec) { + a0.clear() +} + +unsafe fn f76(a0: &mut Vec) -> *mut T1 { + a0.as_mut_ptr().add(a0.len()) +} + +unsafe fn f77(a0: &mut Vec, a1: *const T1, a2: T1) { + let pos = a1.offset_from(a0.as_ptr()) as usize; + a0.insert(pos, a2); +} + +unsafe fn f78(a0: usize, a1: T1) -> Vec { + vec![a1; a0 as usize] +} + +unsafe fn f79(a0: &mut Vec, a1: *const T1, a2: T1) { + let pos = a1.offset_from(a0.as_ptr()) as usize; + a0.insert(pos, a2); +} + +unsafe fn f80(a0: &mut Vec, a1: T1) { + let a0_clone = a1.clone(); + a0.push(a0_clone) +} + +unsafe fn f81(a0: *mut T1) -> *mut T1 { + a0 +} + +unsafe fn f82(a0: *const T1) -> *const T1 { + a0 +} + +unsafe fn f83(a0: *const T1) -> *const T1 { + a0 +} + +unsafe fn f84(a0: *mut T1, a1: usize) -> *mut T1 { + a0.add(a1 as usize) +} + +unsafe fn f85(a0: *const T1, a1: *const T1) -> bool { + a0 != a1 +} +unsafe fn f86(a0: *const T1, a1: *const T1) -> bool { + a0 == a1 +} + +unsafe fn f87(a0: &mut *mut T1) -> *mut T1 { + a0.postfix_inc() +} + +unsafe fn f88(a0: *const T1, a1: *const T1) -> isize { + a0.offset_from(a1) +} + +unsafe fn f89(a0: &mut *mut T1) -> *mut T1 { + a0.prefix_inc() +} + +unsafe fn f90(a0: *const T1, a1: *const T1) -> Vec { + core::slice::from_raw_parts(a0, (a1).offset_from(a0) as usize).to_vec() +} + +unsafe fn f91(a0: Vec) -> Vec { + a0 +} + +unsafe fn f92, T2: Clone>(a0: *mut T2, a1: *mut T2) -> Vec { + core::slice::from_raw_parts(a0, (a1).offset_from(a0) as usize) + .iter() + .map(|x| T1::try_from(x.clone()).ok().unwrap()) + .collect() +} + +unsafe fn f93(a0: &mut Vec) -> *const T1 { + a0.as_ptr() +} + +unsafe fn f94(a0: *const T1, a1: *const T1) -> *const T1 { + core::slice::from_raw_parts(a0, (a1).offset_from(a0) as usize) + .iter() + .max() + .unwrap() +} + +unsafe fn f95(a0: Vec) -> *const T1 { + a0.as_ptr() +} + +unsafe fn f96(a0: Vec) -> *const T1 { + a0.as_ptr().add(a0.len()) +} + +unsafe fn f97(a0: &mut Vec, a1: &mut Vec) { + std::mem::swap(&mut *a0, &mut *a1) +} + +unsafe fn f98(a0: &mut Vec, a1: usize) -> *mut T1 { + if a1 as usize >= a0.len() { + panic!("out of bounds access") + } else { + (a0).as_mut_ptr().add(a1 as usize) + } +} + +unsafe fn f99(a0: &Vec) -> &T1 { + ((a0).last().unwrap()) +} + +unsafe fn f100(a0: &mut Vec>, a1: Vec) { + a0.push(a1.clone()) +} + +unsafe fn f101( + a0: &mut Vec, + a1: *const T1, + a2: *const T1, + a3: *const T1, +) -> *mut T1 { + let __off = a1.offset_from(a0.as_ptr()) as usize; + let count = a3.offset_from(a2) as usize; + a0.splice( + __off..__off, + std::slice::from_raw_parts(a2, count).iter().cloned(), + ); + a0.as_mut_ptr().add(__off) +} + +unsafe fn f102(a0: &mut Vec, a1: usize, a2: T1) { + let __a0 = a1 as usize; + a0.resize(__a0, a2) +} + +unsafe fn f103(a0: &mut Vec, a1: &mut Vec) { + *a0 = std::mem::take(&mut *a1) +} + +unsafe fn f104(a0: Vec) -> *const T1 { + a0.as_ptr().add(a0.len()) +} + +unsafe fn f105(a0: &mut Vec, a1: Vec) { + *a0 = a1.clone() +} + +unsafe fn f106(a0: &mut Vec) { + a0.shrink_to_fit() +} diff --git a/tests/unit/out/refcount/vector_with_allocator.rs b/tests/unit/out/refcount/vector_with_allocator.rs new file mode 100644 index 00000000..89abaf80 --- /dev/null +++ b/tests/unit/out/refcount/vector_with_allocator.rs @@ -0,0 +1,364 @@ +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}; +#[derive(Default)] +pub struct TestAllocator_int_ {} +impl TestAllocator_int_ { + pub fn allocate(&self, n: usize) -> Ptr { + let n: Value = Rc::new(RefCell::new(n)); + return Ptr::alloc_array( + (0..(*n.borrow())) + .map(|_| ::default()) + .collect::>(), + ); + } + pub fn deallocate(&self, p: Ptr, _: usize) { + let p: Value> = Rc::new(RefCell::new(p)); + (*p.borrow()).delete_array(); + } +} +impl Clone for TestAllocator_int_ { + fn clone(&self) -> Self { + let mut this = Self {}; + this + } +} +impl ByteRepr for TestAllocator_int_ { + fn byte_size() -> usize { + 1 + } + fn to_bytes(&self, buf: &mut [u8]) {} + fn from_bytes(buf: &[u8]) -> Self { + Self {} + } +} +#[derive(Default)] +pub struct TestAllocator_double_ {} +impl TestAllocator_double_ { + pub fn allocate(&self, n: usize) -> Ptr { + let n: Value = Rc::new(RefCell::new(n)); + return Ptr::alloc_array( + (0..(*n.borrow())) + .map(|_| ::default()) + .collect::>(), + ); + } + pub fn deallocate(&self, p: Ptr, _: usize) { + let p: Value> = Rc::new(RefCell::new(p)); + (*p.borrow()).delete_array(); + } +} +impl Clone for TestAllocator_double_ { + fn clone(&self) -> Self { + let mut this = Self {}; + this + } +} +impl ByteRepr for TestAllocator_double_ { + fn byte_size() -> usize { + 1 + } + fn to_bytes(&self, buf: &mut [u8]) {} + fn from_bytes(buf: &[u8]) -> Self { + Self {} + } +} +pub fn copy_0(copy_vector: Vec) { + let copy_vector: Value> = Rc::new(RefCell::new(copy_vector)); +} +pub fn fn_1(v: Ptr>, v3: Vec) { + let v3: Value> = Rc::new(RefCell::new(v3)); + v.with_mut(|__v: &mut Vec| __v.push(20)); + let x: Value = >::default(); + let v4: Value>> = Rc::new(RefCell::new((v3.as_pointer()))); + let v2: Value> = Rc::new(RefCell::new(Vec::new())); + (*v2.borrow_mut()).push(0); + (*v2.borrow_mut()).push(1); + (*v2.borrow_mut()).push(3); + (*x.borrow_mut()) = ((v.to_strong().as_pointer() as Ptr) + .offset(2_usize) + .read()); + (v2.as_pointer() as Ptr).offset(0_usize).write(1); + ((if true { + v3.as_pointer() + } else { + v.to_strong().as_pointer() + }) as Ptr) + .offset(0_usize) + .write(7); + (((*v4.borrow()).to_strong().as_pointer()) as Ptr) + .offset(1_usize) + .write(13); + assert!(((*x.borrow()) == 6)); + assert!((((v.to_strong().as_pointer() as Ptr).read()) == 4)); + assert!( + (((v.to_strong().as_pointer() as Ptr) + .offset(1_usize) + .read()) + == 5) + ); + assert!( + (((v.to_strong().as_pointer() as Ptr) + .offset(2_usize) + .read()) + == 6) + ); + assert!((((v.to_strong().as_pointer() as Ptr).to_last().read()) == 20)); + assert!((((v3.as_pointer() as Ptr).offset(0_usize).read()) == 7)); + assert!((((v3.as_pointer() as Ptr).offset(1_usize).read()) == 13)); + v.with_mut(|__v: &mut Vec| __v.push(20)); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let v1: Value> = Rc::new(RefCell::new(Vec::new())); + assert!(((*v1.borrow()).len() == 0_usize)); + assert!((*v1.borrow()).is_empty()); + (*v1.borrow_mut()).push(1); + assert!(!(*v1.borrow()).is_empty()); + (*v1.borrow_mut()).pop(); + assert!((*v1.borrow()).is_empty()); + let s1: Value = Rc::new(RefCell::new((*v1.borrow()).len())); + { + let __a0 = 100_usize as usize; + (*v1.borrow_mut()).resize_with(__a0, || ::default()) + }; + assert!(((*v1.borrow()).len() == 100_usize)); + assert!((((v1.as_pointer() as Ptr).offset(99_usize).read()) == 0)); + (v1.as_pointer() as Ptr).offset(0_usize).write(40); + (v1.as_pointer() as Ptr).offset(99_usize).write(50); + assert!((((v1.as_pointer() as Ptr).offset(0_usize).read()) == 40)); + assert!((((v1.as_pointer() as Ptr).offset(99_usize).read()) == 50)); + let v2: Value> = Rc::new(RefCell::new(Vec::new())); + assert!(((*v2.borrow()).len() == 0_usize)); + (*v2.borrow_mut()).push(1); + (*v2.borrow_mut()).push(2); + (*v2.borrow_mut()).push(3); + assert!(((*v2.borrow()).len() == 3_usize)); + { + let idx = (v2.as_pointer() as Ptr).clone().get_offset(); + (v2.as_pointer() as Ptr>).with_mut(|__v: &mut Vec| __v.remove(idx)); + (v2.as_pointer() as Ptr>).to_strong().as_pointer() as Ptr + }; + assert!(((*v2.borrow()).len() == 2_usize)); + assert!((((v2.as_pointer() as Ptr).offset(0_usize).read()) == 2)); + assert!((((v2.as_pointer() as Ptr).offset(1_usize).read()) == 3)); + { + let __off = (v2.as_pointer() as Ptr).clone().get_offset(); + (*v2.borrow_mut()).insert(__off, 100); + (v2.as_pointer() as Ptr).clone() + }; + ({ copy_0((*v2.borrow()).clone()) }); + assert!(((*v2.borrow()).len() == 3_usize)); + assert!((((v2.as_pointer() as Ptr).offset(0_usize).read()) == 100)); + assert!((((v2.as_pointer() as Ptr).offset(1_usize).read()) == 2)); + assert!((((v2.as_pointer() as Ptr).offset(2_usize).read()) == 3)); + let s2: Value = Rc::new(RefCell::new((*v2.borrow()).len())); + let v3: Value> = Rc::new(RefCell::new(vec![1; 100_usize as usize])); + assert!(((*v3.borrow()).len() == 100_usize)); + let i: Value = Rc::new(RefCell::new(0)); + 'loop_: while ((*i.borrow()) < 100) { + assert!( + (((v3.as_pointer() as Ptr) + .offset(((*i.borrow()) as usize)) + .read()) + == 1) + ); + (*i.borrow_mut()).prefix_inc(); + } + let v6: Value> = Rc::new(RefCell::new(vec![2.0E+0; (*s2.borrow()) as usize])); + assert!(((*v6.borrow()).len() == (*s2.borrow()))); + let i: Value = Rc::new(RefCell::new(0_u32)); + 'loop_: while (((*i.borrow()) as usize) < (*s2.borrow())) { + assert!( + (((v6.as_pointer() as Ptr) + .offset(((*i.borrow()) as usize)) + .read()) + == 2.0E+0) + ); + (*i.borrow_mut()).prefix_inc(); + } + let p1: Value> = Rc::new(RefCell::new((v6.as_pointer() as Ptr))); + assert!((((*p1.borrow()).read()) == 2.0E+0)); + let p2: Value> = Rc::new(RefCell::new((v3.as_pointer() as Ptr))); + assert!((((*p2.borrow()).read()) == 1)); + assert!((((v3.as_pointer() as Ptr).offset(0_usize).read()) == 1)); + assert!((((v3.as_pointer() as Ptr).offset(1_usize).read()) == 1)); + (*p2.borrow()).write((9.9E+1 as i32)); + assert!((((*p2.borrow()).read()) == 99)); + assert!((((v3.as_pointer() as Ptr).offset(0_usize).read()) == 99)); + assert!((((v3.as_pointer() as Ptr).offset(1_usize).read()) == 1)); + (*p2.borrow_mut()).prefix_inc(); + (*p2.borrow()).write(98); + assert!((((v3.as_pointer() as Ptr).offset(0_usize).read()) == 99)); + assert!((((v3.as_pointer() as Ptr).offset(1_usize).read()) == 98)); + assert!(((*v3.borrow()).capacity() == 100_usize)); + assert!(((*v3.borrow()).len() == 100_usize)); + if 200_usize as usize > (*v3.borrow()).capacity() as usize { + let len_0 = (*v3.borrow()).len(); + (*v3.borrow_mut()).reserve_exact(200_usize as usize - len_0 as usize); + }; + assert!(((*v3.borrow()).capacity() == 200_usize)); + assert!(((*v3.borrow()).len() == 100_usize)); + if 50_usize as usize > (*v3.borrow()).capacity() as usize { + let len_0 = (*v3.borrow()).len(); + (*v3.borrow_mut()).reserve_exact(50_usize as usize - len_0 as usize); + }; + assert!(((*v3.borrow()).capacity() == 200_usize)); + assert!(((*v3.borrow()).len() == 100_usize)); + if 200_usize as usize > (*v3.borrow()).capacity() as usize { + let len_0 = (*v3.borrow()).len(); + (*v3.borrow_mut()).reserve_exact(200_usize as usize - len_0 as usize); + }; + assert!(((*v3.borrow()).capacity() == 200_usize)); + assert!(((*v3.borrow()).len() == 100_usize)); + if 201_usize as usize > (*v3.borrow()).capacity() as usize { + let len_0 = (*v3.borrow()).len(); + (*v3.borrow_mut()).reserve_exact(201_usize as usize - len_0 as usize); + }; + assert!(((*v3.borrow()).capacity() == 201_usize)); + assert!(((*v3.borrow()).len() == 100_usize)); + assert!((((v2.as_pointer() as Ptr).to_last().read()) == 3)); + assert!((((v3.as_pointer() as Ptr).to_last().read()) == 1)); + assert!((((v6.as_pointer() as Ptr).to_last().read()) == 2.0E+0)); + let ref0: Ptr = (v6.as_pointer() as Ptr).to_last(); + ref0.write(5.0E+0); + assert!((((v6.as_pointer() as Ptr).to_last().read()) == 5.0E+0)); + let x0: Value = Rc::new(RefCell::new( + ((v6.as_pointer() as Ptr).to_last().read()), + )); + assert!(((*x0.borrow()) == 5.0E+0)); + (*x0.borrow_mut()) = 6.0E+0; + assert!((((v6.as_pointer() as Ptr).to_last().read()) == 5.0E+0)); + let idx: Value = Rc::new(RefCell::new(0)); + assert!( + (((v6.as_pointer() as Ptr) + .offset(((*idx.borrow()) as usize) as isize) + .read()) + == 2.0E+0) + ); + assert!( + (((v6.as_pointer() as Ptr) + .offset((*s2.borrow()).wrapping_sub(1_usize) as isize) + .read()) + == 5.0E+0) + ); + let ref1: Ptr = + (v6.as_pointer() as Ptr).offset((*s2.borrow()).wrapping_sub(1_usize) as isize); + { + let _ptr = ref1.clone(); + _ptr.write(_ptr.read() + 1.5E+0) + }; + assert!( + (((v6.as_pointer() as Ptr) + .offset((*s2.borrow()).wrapping_sub(1_usize) as isize) + .read()) + == 6.5E+0) + ); + let x1: Value = Rc::new(RefCell::new( + ((v6.as_pointer() as Ptr) + .offset((*s2.borrow()).wrapping_sub(1_usize) as isize) + .read()), + )); + assert!(((*x1.borrow()) == 6.5E+0)); + (*x1.borrow_mut()) -= 1.5E+0; + assert!( + (((v6.as_pointer() as Ptr) + .offset((*s2.borrow()).wrapping_sub(1_usize) as isize) + .read()) + == 6.5E+0) + ); + let v7: Value> = Rc::new(RefCell::new(Vec::new())); + let v8: Value> = Rc::new(RefCell::new(Vec::new())); + (*v7.borrow_mut()).push(4); + (*v7.borrow_mut()).push(5); + (*v7.borrow_mut()).push(6); + (*v8.borrow_mut()).push(8); + (*v8.borrow_mut()).push(9); + ({ fn_1(v7.as_pointer(), (*v8.borrow()).clone()) }); + let src: Value> = Rc::new(RefCell::new(Box::new([1_u32, 2_u32, 3_u32]))); + let v9: Value> = Rc::new(RefCell::new({ + let __count = (src.as_pointer() as Ptr) + .offset((3) as isize) + .get_offset() + - (src.as_pointer() as Ptr).get_offset(); + PtrValueIter::new(&(src.as_pointer() as Ptr), __count) + .map(|item| u32::try_from(item).ok().unwrap()) + .collect::>() + })); + assert!(((*v9.borrow()).len() == 3_usize)); + assert!( + ((((v9.as_pointer() as Ptr).offset(0_usize).read()) == 1_u32) + && (((v9.as_pointer() as Ptr).offset(1_usize).read()) == 2_u32)) + && (((v9.as_pointer() as Ptr).offset(2_usize).read()) == 3_u32) + ); + let v10: Value> = Rc::new(RefCell::new({ + let __count = (src.as_pointer() as Ptr) + .offset((3) as isize) + .get_offset() + - (src.as_pointer() as Ptr).get_offset(); + PtrValueIter::new(&(src.as_pointer() as Ptr), __count) + .map(|item| u64::try_from(item).ok().unwrap()) + .collect::>() + })); + assert!(((*v10.borrow()).len() == 3_usize)); + assert!( + ((((v10.as_pointer() as Ptr).offset(0_usize).read()) == 1_u64) + && (((v10.as_pointer() as Ptr).offset(1_usize).read()) == 2_u64)) + && (((v10.as_pointer() as Ptr).offset(2_usize).read()) == 3_u64) + ); + let v11: Value> = Rc::new(RefCell::new({ + let __count = (src.as_pointer() as Ptr) + .offset((3) as isize) + .get_offset() + - (src.as_pointer() as Ptr).get_offset(); + PtrValueIter::new(&(src.as_pointer() as Ptr), __count) + .map(|item| i32::try_from(item).ok().unwrap()) + .collect::>() + })); + assert!(((*v11.borrow()).len() == 3_usize)); + assert!( + ((((v11.as_pointer() as Ptr).offset(0_usize).read()) == 1) + && (((v11.as_pointer() as Ptr).offset(1_usize).read()) == 2)) + && (((v11.as_pointer() as Ptr).offset(2_usize).read()) == 3) + ); + let src1: Value> = Rc::new(RefCell::new(Box::new([1_u32, 2_u32, 3_u32]))); + let v12: Value> = Rc::new(RefCell::new({ + let __count = (src1.as_pointer() as Ptr).to_end().get_offset() + - (src1.as_pointer() as Ptr).get_offset(); + PtrValueIter::new(&(src1.as_pointer() as Ptr), __count).collect::>() + })); + assert!(((*v12.borrow()).len() == 3_usize)); + assert!( + ((((v12.as_pointer() as Ptr).offset(0_usize).read()) == 1_u32) + && (((v12.as_pointer() as Ptr).offset(1_usize).read()) == 2_u32)) + && (((v12.as_pointer() as Ptr).offset(2_usize).read()) == 3_u32) + ); + let buf: Value> = + Rc::new(RefCell::new(Box::new([10_u8, 20_u8, 30_u8, 40_u8, 50_u8]))); + let start: Value> = Rc::new(RefCell::new((buf.as_pointer() as Ptr))); + let len: Value = Rc::new(RefCell::new(5_usize)); + let v13: Value> = Rc::new(RefCell::new({ + let __count = (*start.borrow()) + .offset((*len.borrow()) as isize) + .get_offset() + - (*start.borrow()).get_offset(); + PtrValueIter::new(&(*start.borrow()), __count).collect::>() + })); + assert!(((*v13.borrow()).len() == 5_usize)); + assert!( + ((((v13.as_pointer() as Ptr).offset(0_usize).read()) as i32) == 10) + && ((((v13.as_pointer() as Ptr).offset(4_usize).read()) as i32) == 50) + ); + return ((((*s1.borrow()).wrapping_add((*s2.borrow()))).wrapping_add( + (((v2.as_pointer() as Ptr) + .offset(0_usize as isize) + .read()) as usize), + )) as i32); +} diff --git a/tests/unit/out/unsafe/vector_with_allocator.rs b/tests/unit/out/unsafe/vector_with_allocator.rs new file mode 100644 index 00000000..7482ffe2 --- /dev/null +++ b/tests/unit/out/unsafe/vector_with_allocator.rs @@ -0,0 +1,246 @@ +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; +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct TestAllocator_int_ {} +impl TestAllocator_int_ { + pub unsafe fn allocate(&mut self, mut n: usize) -> *mut i32 { + return Box::leak((0..n).map(|_| 0_i32).collect::>()).as_mut_ptr(); + } + pub unsafe fn deallocate(&mut self, mut p: *mut i32, _: usize) { + ::std::mem::drop(Box::from_raw(::std::slice::from_raw_parts_mut( + p, + libcc2rs::malloc_usable_size(p as *mut ::libc::c_void) / ::std::mem::size_of::(), + ))); + } +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct TestAllocator_double_ {} +impl TestAllocator_double_ { + pub unsafe fn allocate(&mut self, mut n: usize) -> *mut f64 { + return Box::leak((0..n).map(|_| 0.0_f64).collect::>()).as_mut_ptr(); + } + pub unsafe fn deallocate(&mut self, mut p: *mut f64, _: usize) { + ::std::mem::drop(Box::from_raw(::std::slice::from_raw_parts_mut( + p, + libcc2rs::malloc_usable_size(p as *mut ::libc::c_void) / ::std::mem::size_of::(), + ))); + } +} +pub unsafe fn copy_0(mut copy_vector: Vec) {} +pub unsafe fn fn_1(v: *mut Vec, mut v3: Vec) { + (*v).push(20); + let mut x: i32 = 0_i32; + let mut v4: *mut Vec = (&mut v3 as *mut Vec); + let mut v2: Vec = Vec::new(); + v2.push(0); + v2.push(1); + v2.push(3); + x = (&mut (*v))[(2_usize)]; + v2[(0_usize)] = 1; + (if true { &mut v3 } else { &mut (*v) })[(0_usize)] = 7; + (&mut (*v4))[(1_usize)] = 13; + assert!(((x) == (6))); + assert!(((*((*v).first_mut().unwrap())) == (4))); + assert!((((&mut (*v))[(1_usize)]) == (5))); + assert!((((&mut (*v))[(2_usize)]) == (6))); + assert!(((*((*v).last_mut().unwrap())) == (20))); + assert!(((v3[(0_usize)]) == (7))); + assert!(((v3[(1_usize)]) == (13))); + (*v).push(20); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut v1: Vec = Vec::new(); + assert!(((v1.len()) == (0_usize))); + assert!(v1.is_empty()); + v1.push(1); + assert!(!v1.is_empty()); + v1.pop(); + assert!(v1.is_empty()); + let mut s1: usize = v1.len(); + { + let __a0 = 100_usize as usize; + v1.resize_with(__a0, || ::default()) + }; + assert!(((v1.len()) == (100_usize))); + assert!(((v1[(99_usize)]) == (0))); + v1[(0_usize)] = 40; + v1[(99_usize)] = 50; + assert!(((v1[(0_usize)]) == (40))); + assert!(((v1[(99_usize)]) == (50))); + let mut v2: Vec = Vec::new(); + assert!(((v2.len()) == (0_usize))); + v2.push(1); + v2.push(2); + v2.push(3); + assert!(((v2.len()) == (3_usize))); + { + let pos = v2.as_mut_ptr().offset_from(v2.as_ptr()) as usize; + v2.remove(pos); + v2.as_mut_ptr() + }; + assert!(((v2.len()) == (2_usize))); + assert!(((v2[(0_usize)]) == (2))); + assert!(((v2[(1_usize)]) == (3))); + { + let pos = v2.as_mut_ptr().offset_from(v2.as_ptr()) as usize; + v2.insert(pos, 100); + }; + (unsafe { copy_0(v2.clone()) }); + assert!(((v2.len()) == (3_usize))); + assert!(((v2[(0_usize)]) == (100))); + assert!(((v2[(1_usize)]) == (2))); + assert!(((v2[(2_usize)]) == (3))); + let mut s2: usize = v2.len(); + let mut v3: Vec = vec![1; 100_usize as usize]; + assert!(((v3.len()) == (100_usize))); + let mut i: i32 = 0; + 'loop_: while ((i) < (100)) { + assert!(((v3[(i as usize)]) == (1))); + i.prefix_inc(); + } + let mut v6: Vec = vec![2.0E+0; s2 as usize]; + assert!(((v6.len()) == (s2))); + let mut i: u32 = 0_u32; + 'loop_: while ((i as usize) < (s2)) { + assert!(((v6[(i as usize)]) == (2.0E+0))); + i.prefix_inc(); + } + let mut p1: *const f64 = (v6.as_mut_ptr()).cast_const(); + assert!(((*p1) == (2.0E+0))); + let mut p2: *mut i32 = v3.as_mut_ptr(); + assert!(((*p2) == (1))); + assert!(((v3[(0_usize)]) == (1))); + assert!(((v3[(1_usize)]) == (1))); + (*p2) = (9.9E+1 as i32); + assert!(((*p2) == (99))); + assert!(((v3[(0_usize)]) == (99))); + assert!(((v3[(1_usize)]) == (1))); + p2.prefix_inc(); + (*p2) = 98; + assert!(((v3[(0_usize)]) == (99))); + assert!(((v3[(1_usize)]) == (98))); + assert!(((v3.capacity()) == (100_usize))); + assert!(((v3.len()) == (100_usize))); + if 200_usize as usize > v3.capacity() as usize { + let len_0 = v3.len(); + v3.reserve_exact(200_usize as usize - len_0 as usize); + }; + assert!(((v3.capacity()) == (200_usize))); + assert!(((v3.len()) == (100_usize))); + if 50_usize as usize > v3.capacity() as usize { + let len_0 = v3.len(); + v3.reserve_exact(50_usize as usize - len_0 as usize); + }; + assert!(((v3.capacity()) == (200_usize))); + assert!(((v3.len()) == (100_usize))); + if 200_usize as usize > v3.capacity() as usize { + let len_0 = v3.len(); + v3.reserve_exact(200_usize as usize - len_0 as usize); + }; + assert!(((v3.capacity()) == (200_usize))); + assert!(((v3.len()) == (100_usize))); + if 201_usize as usize > v3.capacity() as usize { + let len_0 = v3.len(); + v3.reserve_exact(201_usize as usize - len_0 as usize); + }; + assert!(((v3.capacity()) == (201_usize))); + assert!(((v3.len()) == (100_usize))); + assert!(((*((v2).last_mut().unwrap())) == (3))); + assert!(((*((v3).last_mut().unwrap())) == (1))); + assert!(((*((v6).last_mut().unwrap())) == (2.0E+0))); + let ref0: *mut f64 = ((v6).last_mut().unwrap()); + (*ref0) = 5.0E+0; + assert!(((*((v6).last_mut().unwrap())) == (5.0E+0))); + let mut x0: f64 = (*((v6).last_mut().unwrap())); + assert!(((x0) == (5.0E+0))); + x0 = 6.0E+0; + assert!(((*((v6).last_mut().unwrap())) == (5.0E+0))); + let mut idx: i32 = 0; + assert!(((*&mut (v6)[(idx as usize) as usize]) == (2.0E+0))); + assert!(((*&mut (v6)[(s2).wrapping_sub(1_usize) as usize]) == (5.0E+0))); + let ref1: *mut f64 = &mut (v6)[(s2).wrapping_sub(1_usize) as usize]; + (*ref1) += 1.5E+0; + assert!(((*&mut (v6)[(s2).wrapping_sub(1_usize) as usize]) == (6.5E+0))); + let mut x1: f64 = (*&mut (v6)[(s2).wrapping_sub(1_usize) as usize]); + assert!(((x1) == (6.5E+0))); + x1 -= 1.5E+0; + assert!(((*&mut (v6)[(s2).wrapping_sub(1_usize) as usize]) == (6.5E+0))); + let mut v7: Vec = Vec::new(); + let mut v8: Vec = Vec::new(); + v7.push(4); + v7.push(5); + v7.push(6); + v8.push(8); + v8.push(9); + (unsafe { fn_1(&mut v7 as *mut Vec, v8.clone()) }); + let mut src: [u32; 3] = [1_u32, 2_u32, 3_u32]; + let mut v9: Vec = core::slice::from_raw_parts( + src.as_mut_ptr(), + (src.as_mut_ptr().offset((3) as isize)).offset_from(src.as_mut_ptr()) as usize, + ) + .iter() + .map(|x| u32::try_from(x.clone()).ok().unwrap()) + .collect(); + assert!(((v9.len()) == (3_usize))); + assert!( + (((v9[(0_usize)]) == (1_u32)) && ((v9[(1_usize)]) == (2_u32))) + && ((v9[(2_usize)]) == (3_u32)) + ); + let mut v10: Vec = core::slice::from_raw_parts( + src.as_mut_ptr(), + (src.as_mut_ptr().offset((3) as isize)).offset_from(src.as_mut_ptr()) as usize, + ) + .iter() + .map(|x| u64::try_from(x.clone()).ok().unwrap()) + .collect(); + assert!(((v10.len()) == (3_usize))); + assert!( + (((v10[(0_usize)]) == (1_u64)) && ((v10[(1_usize)]) == (2_u64))) + && ((v10[(2_usize)]) == (3_u64)) + ); + let mut v11: Vec = core::slice::from_raw_parts( + src.as_mut_ptr(), + (src.as_mut_ptr().offset((3) as isize)).offset_from(src.as_mut_ptr()) as usize, + ) + .iter() + .map(|x| i32::try_from(x.clone()).ok().unwrap()) + .collect(); + assert!(((v11.len()) == (3_usize))); + assert!((((v11[(0_usize)]) == (1)) && ((v11[(1_usize)]) == (2))) && ((v11[(2_usize)]) == (3))); + let src1: [u32; 3] = [1_u32, 2_u32, 3_u32]; + let mut v12: Vec = core::slice::from_raw_parts( + src1.as_ptr(), + (src1.as_ptr().add(src1.len())).offset_from(src1.as_ptr()) as usize, + ) + .to_vec(); + assert!(((v12.len()) == (3_usize))); + assert!( + (((v12[(0_usize)]) == (1_u32)) && ((v12[(1_usize)]) == (2_u32))) + && ((v12[(2_usize)]) == (3_u32)) + ); + let mut buf: [u8; 5] = [10_u8, 20_u8, 30_u8, 40_u8, 50_u8]; + let mut start: *const u8 = (buf.as_mut_ptr()).cast_const(); + let mut len: usize = 5_usize; + let mut v13: Vec = core::slice::from_raw_parts( + start, + (start.offset((len) as isize)).offset_from(start) as usize, + ) + .to_vec(); + assert!(((v13.len()) == (5_usize))); + assert!(((v13[(0_usize)] as i32) == (10)) && ((v13[(4_usize)] as i32) == (50))); + return ((((s1).wrapping_add(s2)).wrapping_add(((*&mut (v2)[0_usize as usize]) as usize))) + as i32); +} diff --git a/tests/unit/vector_with_allocator.cpp b/tests/unit/vector_with_allocator.cpp new file mode 100644 index 00000000..48ef9de1 --- /dev/null +++ b/tests/unit/vector_with_allocator.cpp @@ -0,0 +1,182 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +#include +#include +#include +#include + +template struct TestAllocator { + using value_type = T; + + T *allocate(std::size_t n) { return new T[n]; } + + void deallocate(T *p, std::size_t /*n*/) { delete[] p; } +}; + +void copy(std::vector> copy_vector) {} + +void fn(std::vector> &v, + std::vector> v3) { + v.push_back(20); + int x; + std::vector> *v4 = &v3; + std::vector> v2; + v2.push_back(0); + v2.push_back(1); + v2.push_back(3); + x = v[2]; + v2[0] = 1; + (true ? v3 : v)[0] = 7; + (*v4)[1] = 13; + assert(x == 6); + assert(v.front() == 4); + assert(v[1] == 5); + assert(v[2] == 6); + assert(v.back() == 20); + assert(v3[0] == 7); + assert(v3[1] == 13); + v.push_back(20); +} + +int main() { + std::vector> v1; + assert(v1.size() == 0); + assert(v1.empty()); + v1.push_back(1); + assert(!v1.empty()); + v1.pop_back(); + assert(v1.empty()); + + auto s1 = v1.size(); + v1.resize(100); + assert(v1.size() == 100); + assert(v1[99] == 0); + v1[0] = 40; + v1[99] = 50; + assert(v1[0] == 40); + assert(v1[99] == 50); + + std::vector> v2; + assert(v2.size() == 0); + v2.push_back(1); + v2.push_back(2); + v2.push_back(3); + assert(v2.size() == 3); + v2.erase(v2.begin()); + assert(v2.size() == 2); + assert(v2[0] == 2); + assert(v2[1] == 3); + v2.insert(v2.begin(), 100); + copy(v2); + assert(v2.size() == 3); + assert(v2[0] == 100); + assert(v2[1] == 2); + assert(v2[2] == 3); + + auto s2 = v2.size(); + std::vector> v3(100, 1); + assert(v3.size() == 100); + for (int i = 0; i < 100; ++i) + assert(v3[i] == 1); + + std::vector> v6(s2, 2.0); + assert(v6.size() == s2); + for (unsigned i = 0; i < s2; ++i) + assert(v6[i] == 2.0); + + const double *p1 = v6.data(); + assert(*p1 == 2.0); + + int *p2 = v3.data(); + assert(*p2 == 1); + assert(v3[0] == 1); + assert(v3[1] == 1); + *p2 = 99.0; + assert(*p2 == 99); + assert(v3[0] == 99); + assert(v3[1] == 1); + ++p2; + *p2 = 98; + assert(v3[0] == 99); + assert(v3[1] == 98); + assert(v3.capacity() == 100); + assert(v3.size() == 100); + v3.reserve(200); + assert(v3.capacity() == 200); + assert(v3.size() == 100); + v3.reserve(50); + assert(v3.capacity() == 200); + assert(v3.size() == 100); + v3.reserve(200); + assert(v3.capacity() == 200); + assert(v3.size() == 100); + v3.reserve(201); + assert(v3.capacity() == 201); + assert(v3.size() == 100); + assert(v2.back() == 3); + assert(v3.back() == 1); + assert(v6.back() == 2.0); + + double &ref0 = v6.back(); + ref0 = 5.0; + assert(v6.back() == 5.0); + + double x0 = v6.back(); + assert(x0 == 5.0); + x0 = 6.0; + assert(v6.back() == 5.0); + + int idx = 0; + assert(v6.at(idx) == 2.0); + assert(v6.at(s2 - 1) == 5.0); + + double &ref1 = v6.at(s2 - 1); + ref1 += 1.5; + assert(v6.at(s2 - 1) == 6.5); + + double x1 = v6.at(s2 - 1); + assert(x1 == 6.5); + x1 -= 1.5; + assert(v6.at(s2 - 1) == 6.5); + + std::vector> v7; + std::vector> v8; + v7.push_back(4); + v7.push_back(5); + v7.push_back(6); + v8.push_back(8); + v8.push_back(9); + fn(v7, v8); + + uint32_t src[3] = {1, 2, 3}; + + // Same-type iterator-range constructor. + std::vector v9(src, src + 3); + assert(v9.size() == 3); + assert(v9[0] == 1 && v9[1] == 2 && v9[2] == 3); + + // Cross-type widening (uint32_t -> size_t). + std::vector v10(src, src + 3); + assert(v10.size() == 3); + assert(v10[0] == 1 && v10[1] == 2 && v10[2] == 3); + + // Cross-type sign-flip (uint32_t -> int). + std::vector v11(src, src + 3); + assert(v11.size() == 3); + assert(v11[0] == 1 && v11[1] == 2 && v11[2] == 3); + + const uint32_t src1[3] = {1, 2, 3}; + auto v12 = std::vector(src1, std::end(src1)); + assert(v12.size() == 3); + assert(v12[0] == 1 && v12[1] == 2 && v12[2] == 3); + + uint8_t buf[5] = {10, 20, 30, 40, 50}; + const uint8_t *start = buf; + size_t len = 5; + std::vector v13(start, start + len); + assert(v13.size() == 5); + assert(v13[0] == 10 && v13[4] == 50); + + return s1 + s2 + v2.at(0); +}