diff --git a/cpp2rust/compat/platform_flags.h b/cpp2rust/compat/platform_flags.h index 09ceb590..0f563870 100644 --- a/cpp2rust/compat/platform_flags.h +++ b/cpp2rust/compat/platform_flags.h @@ -9,7 +9,7 @@ static inline std::vector getPlatformClangBeginFlags() { std::vector flags = { "-resource-dir=" CLANG_RESOURCE_DIR, - "-I" COMPAT_INCLUDE_DIR, + "-isystem" COMPAT_INCLUDE_DIR, "-D_FORTIFY_SOURCE=0", }; #ifdef MACOS_SDK_PATH diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 703343d6..cab732b0 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -276,7 +276,7 @@ bool Converter::Convert(clang::Decl *decl) { return TraverseDecl(decl); } bool Converter::VisitTranslationUnitDecl(clang::TranslationUnitDecl *decl) { for (auto *child : decl->decls()) { - if (IsConvertibleDecl(child) && + if (IsUserDefinedDecl(child) && (IsInMainFile(child) || !decl_ids_.contains(GetID(child)))) { Convert(child); } diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 4f60cf64..051aed2d 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -129,7 +129,7 @@ bool IsInMainFile(const clang::Decl *decl) { return src_mgr.isInMainFile(src_mgr.getExpansionLoc(loc)); } -bool IsConvertibleDecl(const clang::Decl *decl) { +bool IsUserDefinedDecl(const clang::Decl *decl) { const auto &ctx = decl->getASTContext(); const auto &src_mgr = ctx.getSourceManager(); const auto src_loc = decl->getLocation(); @@ -138,6 +138,21 @@ bool IsConvertibleDecl(const clang::Decl *decl) { !src_mgr.isInSystemMacro(src_loc); } +bool RefersToUserDefinedDecl(const clang::Expr *expr) { + expr = expr->IgnoreParenImpCasts(); + const clang::Decl *decl = nullptr; + if (const auto *call = llvm::dyn_cast(expr)) { + decl = call->getDirectCallee(); + } else if (const auto *ref = llvm::dyn_cast(expr)) { + decl = ref->getDecl(); + } else if (const auto *member = llvm::dyn_cast(expr)) { + decl = member->getMemberDecl(); + } else if (const auto *ctor = llvm::dyn_cast(expr)) { + decl = ctor->getConstructor(); + } + return decl && IsUserDefinedDecl(decl); +} + bool IsUnsignedArithOp(const clang::BinaryOperator *expr) { clang::QualType lhs_type; clang::QualType rhs_type; diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index aa5d0c2b..c208ea1c 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -39,7 +39,9 @@ bool IsComparisonWithNullOp(const clang::BinaryOperator *expr); bool IsInMainFile(const clang::Decl *decl); -bool IsConvertibleDecl(const clang::Decl *decl); +bool IsUserDefinedDecl(const clang::Decl *decl); + +bool RefersToUserDefinedDecl(const clang::Expr *expr); bool IsUnsignedArithOp(const clang::BinaryOperator *expr); diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index e2b444f4..c86f903a 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -385,6 +385,9 @@ search(std::unordered_multimap &map, const std::string &txt, } TranslationRule::ExprRule *search(const clang::Expr *expr) { + if (RefersToUserDefinedDecl(expr)) { + return nullptr; + } auto qualified_name = ToString(expr); auto [rule, subs] = search(exprs_, qualified_name, GetExprMapKey(qualified_name)); @@ -598,7 +601,8 @@ const TranslationRule::ExprRule *GetExprRule(const clang::Expr *expr) { std::string MapFunctionName(const clang::FunctionDecl *decl) { assert(decl); - if (exprs_.contains(GetExprMapKey(ToString(decl)))) { + if (!IsUserDefinedDecl(decl) && + exprs_.contains(GetExprMapKey(ToString(decl)))) { return std::format("libcc2rs::{}_{}", decl->getNameAsString(), model_ == Model::kRefCount ? "refcount" : "unsafe"); } diff --git a/tests/unit/out/refcount/user_defined_same_as_libc.rs b/tests/unit/out/refcount/user_defined_same_as_libc.rs new file mode 100644 index 00000000..599f7bb3 --- /dev/null +++ b/tests/unit/out/refcount/user_defined_same_as_libc.rs @@ -0,0 +1,29 @@ +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 fopen_0(path: Ptr, mode: Ptr) -> Ptr<::std::fs::File> { + let path: Value> = Rc::new(RefCell::new(path)); + let mode: Value> = Rc::new(RefCell::new(mode)); + (*path.borrow()).clone(); + (*mode.borrow()).clone(); + return Ptr::null(); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let fp: Value> = Rc::new(RefCell::new( + ({ + let _path: Ptr = Ptr::from_string_literal("/tmp/irrelevant-file"); + let _mode: Ptr = Ptr::from_string_literal("r"); + fopen_0(_path, _mode) + }), + )); + assert!(((((*fp.borrow()).is_null()) as i32) != 0)); + return 0; +} diff --git a/tests/unit/out/unsafe/user_defined_same_as_libc.rs b/tests/unit/out/unsafe/user_defined_same_as_libc.rs new file mode 100644 index 00000000..2b284523 --- /dev/null +++ b/tests/unit/out/unsafe/user_defined_same_as_libc.rs @@ -0,0 +1,27 @@ +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 unsafe fn fopen_0(mut path: *const u8, mut mode: *const u8) -> *mut ::std::fs::File { + &(path); + &(mode); + return std::ptr::null_mut(); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut fp: *mut ::std::fs::File = (unsafe { + let _path: *const u8 = (b"/tmp/irrelevant-file\0".as_ptr().cast_mut()).cast_const(); + let _mode: *const u8 = (b"r\0".as_ptr().cast_mut()).cast_const(); + fopen_0(_path, _mode) + }); + assert!(((((fp).is_null()) as i32) != 0)); + return 0; +} diff --git a/tests/unit/user_defined_same_as_libc.c b/tests/unit/user_defined_same_as_libc.c new file mode 100644 index 00000000..57863b8a --- /dev/null +++ b/tests/unit/user_defined_same_as_libc.c @@ -0,0 +1,14 @@ +#include +#include + +FILE *fopen(const char *path, const char *mode) { + (void)path; + (void)mode; + return NULL; +} + +int main() { + FILE *fp = fopen("/tmp/irrelevant-file", "r"); + assert(fp == NULL); + return 0; +}