Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 35 additions & 24 deletions cpp2rust/cpp_rule_preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,21 +469,13 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
return ctx.getCanonicalType(spec);
}

clang::QualType
getDefaultArg(clang::TemplateDecl *decl,
const clang::TemplateTypeParmDecl *parm,
llvm::ArrayRef<clang::TemplateArgument> currentArgs) {
clang::QualType type = parm->getDefaultArgument().getArgument().getAsType();
if (!type->isDependentType()) {
return type;
}

clang::Sema::InstantiatingTemplate Inst(*sema_, loc_, decl);
clang::QualType getSubstType(const clang::Sema::InstantiatingTemplate &Inst,
clang::QualType type,
llvm::ArrayRef<clang::TemplateArgument> args) {
assert(!Inst.isInvalid() && "Invalid instantiation context");

clang::MultiLevelTemplateArgumentList mtal;
mtal.setKind(clang::TemplateSubstitutionKind::Rewrite);
mtal.addOuterTemplateArguments(currentArgs);
mtal.addOuterTemplateArguments(args);

clang::TypeSourceInfo *tsi =
sema_->SubstType(sema_->Context.getTrivialTypeSourceInfo(type), mtal,
Expand All @@ -492,6 +484,19 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
return tsi->getType();
}

clang::QualType
getDefaultArg(clang::TemplateDecl *decl,
const clang::TemplateTypeParmDecl *parm,
llvm::ArrayRef<clang::TemplateArgument> currentArgs) {
clang::QualType type = parm->getDefaultArgument().getArgument().getAsType();
if (!type->isDependentType()) {
return type;
}

const clang::Sema::InstantiatingTemplate Inst(*sema_, loc_, decl);
return getSubstType(Inst, type, currentArgs);
}

clang::VarDecl *createVarDecl(clang::QualType type, llvm::StringRef name,
clang::StorageClass sclass = clang::SC_None) {
clang::ASTContext &ctx = sema_->Context;
Expand Down Expand Up @@ -553,6 +558,10 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
} else if (const auto *nttp =
llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(param)) {
clang::QualType type = nttp->getType();
if (type->isDependentType()) {
const clang::Sema::InstantiatingTemplate Inst(*sema_, loc_, decl);
type = getSubstType(Inst, type, out);
}
clang::DeclRefExpr *var =
createConstexprDeclRefExpr(type, param->getName());
out.emplace_back(var, true);
Expand Down Expand Up @@ -713,7 +722,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
clang::TemplateArgumentListInfo explicitTArgs;

{
clang::Sema::InstantiatingTemplate Inst(*sema_, loc_, decl);
const clang::Sema::InstantiatingTemplate Inst(*sema_, loc_, decl);
assert(!Inst.isInvalid() && "Invalid instantiation context");
for (const auto &argloc : lookup.explicitArgs) {
const auto &arg = argloc.getArgument();
Expand All @@ -724,16 +733,8 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {

clang::TemplateArgument inst;
if (arg.getKind() == clang::TemplateArgument::Type) {
clang::QualType type = arg.getAsType();
clang::MultiLevelTemplateArgumentList mtal;
mtal.setKind(clang::TemplateSubstitutionKind::Rewrite);
mtal.addOuterTemplateArguments(ruleTArgs);

clang::TypeSourceInfo *tsi =
sema_->SubstType(sema_->Context.getTrivialTypeSourceInfo(type),
mtal, loc_, clang::DeclarationName());
assert(tsi && "Template argument type instantiation failed");
inst = clang::TemplateArgument(tsi->getType());
inst = clang::TemplateArgument(
getSubstType(Inst, arg.getAsType(), ruleTArgs));
} else if (arg.getKind() == clang::TemplateArgument::Expression) {
if (auto *expr =
llvm::dyn_cast<clang::DeclRefExpr>(arg.getAsExpr())) {
Expand All @@ -753,7 +754,17 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
}
}

clang::DeclarationName &name = lookup.name;
clang::DeclarationName name = lookup.name;
if (clang::QualType nameType = name.getCXXNameType();
!nameType.isNull() && nameType->isDependentType()) {
const clang::Sema::InstantiatingTemplate Inst(*sema_, loc_, decl);
assert(!Inst.isInvalid() && "Invalid instantiation context");
clang::MultiLevelTemplateArgumentList mtal;
mtal.setKind(clang::TemplateSubstitutionKind::Rewrite);
mtal.addOuterTemplateArguments(ruleTArgs);
name = sema_->SubstDeclarationNameInfo({name, loc_}, mtal).getName();
}

clang::OverloadCandidateSet candidates(loc_, csk);
switch (lookup.kind) {
case LookupKind::RegularName:
Expand Down
18 changes: 18 additions & 0 deletions rules/functional/src.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

#include <functional>

template <typename T1> using t1 = std::reference_wrapper<T1>;

template <typename T1> std::reference_wrapper<T1> f1(T1 &a0) {
return std::reference_wrapper<T1>(a0);
}

template <typename T1> T1 &f2(const std::reference_wrapper<T1> &a0) {
return a0.operator T1 &();
}

template <typename T1> T1 &f3(const std::reference_wrapper<T1> &a0) {
return a0.get();
}
20 changes: 20 additions & 0 deletions rules/functional/tgt_refcount.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

use libcc2rs::*;

fn t1<T1>() -> Ptr<T1> {
Ptr::null()
}

fn f1<T1>(a0: Ptr<T1>) -> Ptr<T1> {
a0
}

fn f2<T1>(a0: Ptr<T1>) -> Ptr<T1> {
a0.clone()
}

fn f3<T1>(a0: Ptr<T1>) -> Ptr<T1> {
a0.clone()
}
18 changes: 18 additions & 0 deletions rules/functional/tgt_unsafe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

fn t1<T1>() -> *mut T1 {
Default::default()
}

unsafe fn f1<T1>(a0: *mut T1) -> *mut T1 {
a0
}

unsafe fn f2<T1>(a0: *mut T1) -> *mut T1 {
a0
}

unsafe fn f3<T1>(a0: *mut T1) -> *mut T1 {
a0
}
4 changes: 4 additions & 0 deletions rules/src/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ pub mod fnmatch_tgt_unsafe;
pub mod fstream_tgt_refcount;
#[path = r#"../fstream/tgt_unsafe.rs"#]
pub mod fstream_tgt_unsafe;
#[path = r#"../functional/tgt_refcount.rs"#]
pub mod functional_tgt_refcount;
#[path = r#"../functional/tgt_unsafe.rs"#]
pub mod functional_tgt_unsafe;
#[path = r#"../ifaddrs/tgt_unsafe.rs"#]
pub mod ifaddrs_tgt_unsafe;
#[path = r#"../initializer_list/tgt_unsafe.rs"#]
Expand Down
98 changes: 98 additions & 0 deletions tests/unit/out/refcount/reference_wrapper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
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 Point {
pub x: Value<i32>,
pub y: Value<i32>,
}
impl Clone for Point {
fn clone(&self) -> Self {
let mut this = Self {
x: Rc::new(RefCell::new((*self.x.borrow()))),
y: Rc::new(RefCell::new((*self.y.borrow()))),
};
this
}
}
impl ByteRepr for Point {
fn byte_size() -> usize {
8
}
fn to_bytes(&self, buf: &mut [u8]) {
(*self.x.borrow()).to_bytes(&mut buf[0..4]);
(*self.y.borrow()).to_bytes(&mut buf[4..8]);
}
fn from_bytes(buf: &[u8]) -> Self {
Self {
x: Rc::new(RefCell::new(<i32>::from_bytes(&buf[0..4]))),
y: Rc::new(RefCell::new(<i32>::from_bytes(&buf[4..8]))),
}
}
}
pub fn set_0(ref_: Ptr<i32>, val: i32) {
let ref_: Value<Ptr<i32>> = Rc::new(RefCell::new(ref_));
let val: Value<i32> = Rc::new(RefCell::new(val));
(*ref_.borrow()).clone().write((*val.borrow()));
}
pub fn read_1(ref_: Ptr<i32>) -> i32 {
let ref_: Value<Ptr<i32>> = Rc::new(RefCell::new(ref_));
let r: Ptr<i32> = (*ref_.borrow()).clone();
return (r.read());
}
pub fn main() {
std::process::exit(main_0());
}
fn main_0() -> i32 {
let i1: Value<i32> = Rc::new(RefCell::new(10));
let ref_1: Value<Ptr<i32>> = Rc::new(RefCell::new(i1.as_pointer()));
(*ref_1.borrow()).clone().write(20);
let i2: Ptr<i32> = (*ref_1.borrow()).clone();
{
let _ptr = i2.clone();
_ptr.write(_ptr.read() + 5)
};
write!(libcc2rs::cout(), "{:}\n", (*i1.borrow()),);
let i3: Value<i32> = Rc::new(RefCell::new(1));
let i4: Value<i32> = Rc::new(RefCell::new(2));
let ref_3: Value<Ptr<i32>> = Rc::new(RefCell::new(i3.as_pointer()));
let ref_4: Value<Ptr<i32>> = Rc::new(RefCell::new(i4.as_pointer()));
let __rhs = ((*ref_4.borrow()).clone().read());
(*ref_3.borrow()).clone().write(__rhs);
write!(
libcc2rs::cout(),
"{:} {:}\n",
(*i3.borrow()),
(*i4.borrow()),
);
({ set_0((*ref_1.borrow()).clone(), 99) });
write!(
libcc2rs::cout(),
"{:} {:}\n",
(*i1.borrow()),
({ read_1((*ref_1.borrow()).clone(),) }),
);
let point: Value<Point> = Rc::new(RefCell::new(Point {
x: Rc::new(RefCell::new(3)),
y: Rc::new(RefCell::new(4)),
}));
let point_ref: Value<Ptr<Point>> = Rc::new(RefCell::new(point.as_pointer()));
(*(*(*point_ref.borrow()).clone().upgrade().deref())
.x
.borrow_mut()) = 30;
(*(*(*point_ref.borrow()).clone().upgrade().deref())
.y
.borrow_mut()) = 40;
write!(
libcc2rs::cout(),
"{:} {:}\n",
(*(*point.borrow()).x.borrow()),
(*(*point.borrow()).y.borrow()),
);
return 0;
}
91 changes: 91 additions & 0 deletions tests/unit/out/unsafe/reference_wrapper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
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 Point {
pub x: i32,
pub y: i32,
}
pub unsafe fn set_0(mut ref_: *mut i32, mut val: i32) {
(*ref_) = val;
}
pub unsafe fn read_1(mut ref_: *mut i32) -> i32 {
let r: *mut i32 = ref_;
return (*r);
}
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
}
}
unsafe fn main_0() -> i32 {
let mut i1: i32 = 10;
let mut ref_1: *mut i32 = &mut i1;
(*ref_1) = 20;
let i2: *mut i32 = ref_1;
(*i2) += 5;
write!(
std::fs::File::from_raw_fd(
std::io::stdout()
.as_fd()
.try_clone_to_owned()
.unwrap()
.into_raw_fd(),
),
"{:}\n",
i1,
);
let mut i3: i32 = 1;
let mut i4: i32 = 2;
let mut ref_3: *mut i32 = &mut i3;
let mut ref_4: *mut i32 = &mut i4;
(*ref_3) = (*ref_4);
write!(
std::fs::File::from_raw_fd(
std::io::stdout()
.as_fd()
.try_clone_to_owned()
.unwrap()
.into_raw_fd(),
),
"{:} {:}\n",
i3,
i4,
);
(unsafe { set_0(ref_1.clone(), 99) });
write!(
std::fs::File::from_raw_fd(
std::io::stdout()
.as_fd()
.try_clone_to_owned()
.unwrap()
.into_raw_fd(),
),
"{:} {:}\n",
i1,
(unsafe { read_1(ref_1.clone(),) }),
);
let mut point: Point = Point { x: 3, y: 4 };
let mut point_ref: *mut Point = &mut point;
(*point_ref).x = 30;
(*point_ref).y = 40;
write!(
std::fs::File::from_raw_fd(
std::io::stdout()
.as_fd()
.try_clone_to_owned()
.unwrap()
.into_raw_fd(),
),
"{:} {:}\n",
point.x,
point.y,
);
return 0;
}
Loading
Loading