Skip to content

Commit cab6a2b

Browse files
authored
Key rules through explicit casts and implicit wrappers (#556)
1 parent 839bbc2 commit cab6a2b

11 files changed

Lines changed: 181 additions & 1 deletion

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2741,7 +2741,8 @@ bool Converter::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
27412741
case clang::Stmt::CXXReinterpretCastExprClass:
27422742
case clang::Stmt::CXXStaticCastExprClass:
27432743
case clang::Stmt::CStyleCastExprClass:
2744-
if (expr->getType() == sub_expr->getType()) {
2744+
if (expr->getType() == sub_expr->getType() ||
2745+
(expr->getCastKind() == clang::CK_NoOp && type->isRecordType())) {
27452746
return Convert(sub_expr);
27462747
}
27472748
if (type->isFunctionPointerType() ||

‎cpp2rust/converter/models/boxed_vars.cpp‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "converter/models/boxed_vars.h"
55

66
#include <clang/AST/RecursiveASTVisitor.h>
7+
#include <clang/Basic/SourceManager.h>
78

89
#include <algorithm>
910
#include <unordered_map>
@@ -110,6 +111,14 @@ class AddressTakenVisitor
110111

111112
bool shouldVisitTemplateInstantiations() const { return true; }
112113

114+
bool TraverseDecl(clang::Decl *decl) {
115+
if (decl && !llvm::isa<clang::TranslationUnitDecl>(decl) &&
116+
ctx_.getSourceManager().isInSystemHeader(decl->getLocation())) {
117+
return true;
118+
}
119+
return RecursiveASTVisitor::TraverseDecl(decl);
120+
}
121+
113122
// Only the semantic form of an initializer list is converted, in which the
114123
// values of variables are read through lvalue-to-rvalue conversions.
115124
bool TraverseInitListExpr(clang::InitListExpr *expr,

‎cpp2rust/converter/rules/rules_loader.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,10 @@ std::string DeclKey(const clang::NamedDecl *decl) {
473473
}
474474

475475
std::string ExprKey(clang::ASTContext &ctx, const clang::Expr *expr) {
476+
expr = RuleDecls::SkipImplicit(expr);
477+
if (auto cast = llvm::dyn_cast<clang::ExplicitCastExpr>(expr)) {
478+
return ExprKey(ctx, cast->getSubExpr());
479+
}
476480
expr = expr->IgnoreParenImpCasts();
477481
if (llvm::isa<clang::IntegerLiteral, clang::AtomicExpr>(expr) &&
478482
expr->getBeginLoc().isMacroID()) {

‎rules/chrono/src_cxx20.cpp‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
#include <chrono>
5+
6+
using t1 = std::chrono::day;
7+
8+
std::chrono::day f1(unsigned a0) { return std::chrono::day(a0); }
9+
10+
unsigned f2(const std::chrono::day &a0) { return static_cast<unsigned>(a0); }

‎rules/chrono/tgt_unsafe.rs‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
fn t1() -> u32 {
5+
0_u32
6+
}
7+
8+
unsafe fn f1(a0: u32) -> u32 {
9+
a0
10+
}
11+
12+
unsafe fn f2(a0: u32) -> u32 {
13+
a0
14+
}

‎rules/fs_path/src_cxx17.cpp‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
#include <filesystem>
5+
#include <string>
6+
7+
using t1 = std::filesystem::path;
8+
9+
std::filesystem::path f1(const char *a0) { return std::filesystem::path(a0); }
10+
11+
std::string f2(const std::filesystem::path &a0) {
12+
return static_cast<std::string>(a0);
13+
}

‎rules/fs_path/tgt_refcount.rs‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
use libcc2rs::*;
5+
6+
fn t1() -> Vec<i8> {
7+
vec![0]
8+
}
9+
10+
fn f1(a0: Ptr<i8>) -> Vec<i8> {
11+
let mut __v = Vec::new();
12+
a0.with_c_str(|__s| __v.extend_from_slice(__s));
13+
__v.push(0);
14+
__v
15+
}
16+
17+
fn f2(a0: Vec<i8>) -> Vec<i8> {
18+
a0
19+
}

‎rules/fs_path/tgt_unsafe.rs‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
fn t1() -> Vec<libc::c_char> {
5+
vec![0]
6+
}
7+
8+
unsafe fn f1(a0: *const libc::c_char) -> Vec<libc::c_char> {
9+
let mut __v = ::std::ffi::CStr::from_ptr(a0)
10+
.to_bytes()
11+
.iter()
12+
.map(|&__b| __b as libc::c_char)
13+
.collect::<Vec<libc::c_char>>();
14+
__v.push(0);
15+
__v
16+
}
17+
18+
unsafe fn f2(a0: Vec<libc::c_char>) -> Vec<libc::c_char> {
19+
a0
20+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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 main() {
10+
__cpp2rust_init_globals();
11+
std::process::exit(main_0());
12+
}
13+
fn main_0() -> i32 {
14+
let mut n: u32 = 17_u32;
15+
let d: Value<u32> = Rc::new(RefCell::new(n));
16+
assert!(((*d.borrow()) == 17_u32));
17+
let mut name: Ptr<i8> = Ptr::<i8>::from_string_literal(b"dir/file.txt");
18+
let p: Value<Vec<i8>> = Rc::new(RefCell::new({
19+
let mut __v = Vec::new();
20+
name.with_c_str(|__s| __v.extend_from_slice(__s));
21+
__v.push(0);
22+
__v
23+
}));
24+
let mut s: Vec<i8> = (*p.borrow()).clone();
25+
assert!(((s.len() - 1) == 12_usize));
26+
assert!(
27+
Ptr::<i8>::from_string_literal(b"dir/file.txt")
28+
.with_c_str(|__s| s[..s.len().saturating_sub(1)] == *__s)
29+
);
30+
return 0;
31+
}
32+
pub fn __cpp2rust_init_globals() {}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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 fn main() {
10+
unsafe {
11+
__cpp2rust_init_globals();
12+
std::process::exit(main_0() as i32);
13+
}
14+
}
15+
unsafe fn main_0() -> i32 {
16+
let mut n: u32 = 17_u32;
17+
let mut d: u32 = n;
18+
assert!(((d) == (17_u32)));
19+
let mut name: *const libc::c_char = c"dir/file.txt".as_ptr();
20+
let mut p: Vec<libc::c_char> = {
21+
let mut __v = ::std::ffi::CStr::from_ptr(name)
22+
.to_bytes()
23+
.iter()
24+
.map(|&__b| __b as libc::c_char)
25+
.collect::<Vec<libc::c_char>>();
26+
__v.push(0);
27+
__v
28+
};
29+
let mut s: Vec<libc::c_char> = p;
30+
assert!(((s.len() - 1) == (12_usize)));
31+
assert!(
32+
s == {
33+
let s = c"dir/file.txt".as_ptr();
34+
std::slice::from_raw_parts(s, (0..).take_while(|&i| *s.add(i) != 0).count() + 1)
35+
.to_vec()
36+
}
37+
);
38+
return 0;
39+
}
40+
pub unsafe fn __cpp2rust_init_globals() {}

0 commit comments

Comments
 (0)