Skip to content

Commit f4ba247

Browse files
authored
Don't map user-defined expressions (#123)
If the user code redefines strchr, don't apply the translation rules on the user-defined strchr, instead call the user-defined strchr.
1 parent a54bbfd commit f4ba247

8 files changed

Lines changed: 96 additions & 5 deletions

File tree

cpp2rust/compat/platform_flags.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
static inline std::vector<std::string> getPlatformClangBeginFlags() {
1010
std::vector<std::string> flags = {
1111
"-resource-dir=" CLANG_RESOURCE_DIR,
12-
"-I" COMPAT_INCLUDE_DIR,
12+
"-isystem" COMPAT_INCLUDE_DIR,
1313
"-D_FORTIFY_SOURCE=0",
1414
};
1515
#ifdef MACOS_SDK_PATH

cpp2rust/converter/converter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ bool Converter::Convert(clang::Decl *decl) { return TraverseDecl(decl); }
276276

277277
bool Converter::VisitTranslationUnitDecl(clang::TranslationUnitDecl *decl) {
278278
for (auto *child : decl->decls()) {
279-
if (IsConvertibleDecl(child) &&
279+
if (IsUserDefinedDecl(child) &&
280280
(IsInMainFile(child) || !decl_ids_.contains(GetID(child)))) {
281281
Convert(child);
282282
}

cpp2rust/converter/converter_lib.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ bool IsInMainFile(const clang::Decl *decl) {
129129
return src_mgr.isInMainFile(src_mgr.getExpansionLoc(loc));
130130
}
131131

132-
bool IsConvertibleDecl(const clang::Decl *decl) {
132+
bool IsUserDefinedDecl(const clang::Decl *decl) {
133133
const auto &ctx = decl->getASTContext();
134134
const auto &src_mgr = ctx.getSourceManager();
135135
const auto src_loc = decl->getLocation();
@@ -138,6 +138,21 @@ bool IsConvertibleDecl(const clang::Decl *decl) {
138138
!src_mgr.isInSystemMacro(src_loc);
139139
}
140140

141+
bool RefersToUserDefinedDecl(const clang::Expr *expr) {
142+
expr = expr->IgnoreParenImpCasts();
143+
const clang::Decl *decl = nullptr;
144+
if (const auto *call = llvm::dyn_cast<clang::CallExpr>(expr)) {
145+
decl = call->getDirectCallee();
146+
} else if (const auto *ref = llvm::dyn_cast<clang::DeclRefExpr>(expr)) {
147+
decl = ref->getDecl();
148+
} else if (const auto *member = llvm::dyn_cast<clang::MemberExpr>(expr)) {
149+
decl = member->getMemberDecl();
150+
} else if (const auto *ctor = llvm::dyn_cast<clang::CXXConstructExpr>(expr)) {
151+
decl = ctor->getConstructor();
152+
}
153+
return decl && IsUserDefinedDecl(decl);
154+
}
155+
141156
bool IsUnsignedArithOp(const clang::BinaryOperator *expr) {
142157
clang::QualType lhs_type;
143158
clang::QualType rhs_type;

cpp2rust/converter/converter_lib.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ bool IsComparisonWithNullOp(const clang::BinaryOperator *expr);
3939

4040
bool IsInMainFile(const clang::Decl *decl);
4141

42-
bool IsConvertibleDecl(const clang::Decl *decl);
42+
bool IsUserDefinedDecl(const clang::Decl *decl);
43+
44+
bool RefersToUserDefinedDecl(const clang::Expr *expr);
4345

4446
bool IsUnsignedArithOp(const clang::BinaryOperator *expr);
4547

cpp2rust/converter/mapper.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,9 @@ search(std::unordered_multimap<std::string, T> &map, const std::string &txt,
385385
}
386386

387387
TranslationRule::ExprRule *search(const clang::Expr *expr) {
388+
if (RefersToUserDefinedDecl(expr)) {
389+
return nullptr;
390+
}
388391
auto qualified_name = ToString(expr);
389392
auto [rule, subs] =
390393
search(exprs_, qualified_name, GetExprMapKey(qualified_name));
@@ -598,7 +601,8 @@ const TranslationRule::ExprRule *GetExprRule(const clang::Expr *expr) {
598601

599602
std::string MapFunctionName(const clang::FunctionDecl *decl) {
600603
assert(decl);
601-
if (exprs_.contains(GetExprMapKey(ToString(decl)))) {
604+
if (!IsUserDefinedDecl(decl) &&
605+
exprs_.contains(GetExprMapKey(ToString(decl)))) {
602606
return std::format("libcc2rs::{}_{}", decl->getNameAsString(),
603607
model_ == Model::kRefCount ? "refcount" : "unsafe");
604608
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
extern crate libcc2rs;
2+
use libcc2rs::*;
3+
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::io::prelude::*;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::AsFd;
8+
use std::rc::{Rc, Weak};
9+
pub fn fopen_0(path: Ptr<u8>, mode: Ptr<u8>) -> Ptr<::std::fs::File> {
10+
let path: Value<Ptr<u8>> = Rc::new(RefCell::new(path));
11+
let mode: Value<Ptr<u8>> = Rc::new(RefCell::new(mode));
12+
(*path.borrow()).clone();
13+
(*mode.borrow()).clone();
14+
return Ptr::null();
15+
}
16+
pub fn main() {
17+
std::process::exit(main_0());
18+
}
19+
fn main_0() -> i32 {
20+
let fp: Value<Ptr<::std::fs::File>> = Rc::new(RefCell::new(
21+
({
22+
let _path: Ptr<u8> = Ptr::from_string_literal("/tmp/irrelevant-file");
23+
let _mode: Ptr<u8> = Ptr::from_string_literal("r");
24+
fopen_0(_path, _mode)
25+
}),
26+
));
27+
assert!(((((*fp.borrow()).is_null()) as i32) != 0));
28+
return 0;
29+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
pub unsafe fn fopen_0(mut path: *const u8, mut mode: *const u8) -> *mut ::std::fs::File {
10+
&(path);
11+
&(mode);
12+
return std::ptr::null_mut();
13+
}
14+
pub fn main() {
15+
unsafe {
16+
std::process::exit(main_0() as i32);
17+
}
18+
}
19+
unsafe fn main_0() -> i32 {
20+
let mut fp: *mut ::std::fs::File = (unsafe {
21+
let _path: *const u8 = (b"/tmp/irrelevant-file\0".as_ptr().cast_mut()).cast_const();
22+
let _mode: *const u8 = (b"r\0".as_ptr().cast_mut()).cast_const();
23+
fopen_0(_path, _mode)
24+
});
25+
assert!(((((fp).is_null()) as i32) != 0));
26+
return 0;
27+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <assert.h>
2+
#include <stdio.h>
3+
4+
FILE *fopen(const char *path, const char *mode) {
5+
(void)path;
6+
(void)mode;
7+
return NULL;
8+
}
9+
10+
int main() {
11+
FILE *fp = fopen("/tmp/irrelevant-file", "r");
12+
assert(fp == NULL);
13+
return 0;
14+
}

0 commit comments

Comments
 (0)