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
6 changes: 2 additions & 4 deletions rapx/src/analysis/core/alias_analysis/default/alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,6 @@ impl<'tcx> MopGraph<'tcx> {
}

pub fn is_no_alias_intrinsic(def_id: DefId) -> bool {
if def_id == call_mut() || def_id == clone() || def_id == take() {
return true;
}
return false;
let v = [call_mut_opt(), clone_opt(), take_opt()];
contains(&v, def_id)
}
8 changes: 1 addition & 7 deletions rapx/src/analysis/core/alias_analysis/default/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,13 +423,7 @@ impl<'tcx> MopGraph<'tcx> {
} => {
if let Operand::Constant(c) = func {
if let &ty::FnDef(id, ..) = c.ty().kind() {
// for no_std crates without using alloc,
// dealloc will be never found, thus call dealloc_opt here
if id == drop()
|| id == drop_in_place()
|| id == manually_drop()
|| dealloc_opt().map(|f| f == id).unwrap_or(false)
{
if is_drop_fn(id) {
cur_bb.terminator = Term::Drop(terminator.clone());
} else {
cur_bb.terminator = Term::Call(terminator.clone());
Expand Down
10 changes: 5 additions & 5 deletions rapx/src/analysis/core/alias_analysis/default/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,14 @@ impl<'tcx> AliasAnalyzer<'tcx> {

fn handle_conor_cases(&mut self) {
let cases = [
copy_from_nonoverlapping(),
copy_to_nonoverlapping(),
copy_to(),
copy_from(),
copy_from_nonoverlapping_opt(),
copy_to_nonoverlapping_opt(),
copy_to_opt(),
copy_from_opt(),
];
let alias = MopAliasPair::new(1, true, true, 2, true, true);
for (key, value) in self.fn_map.iter_mut() {
if cases.iter().any(|lock| lock == key) {
if contains(&cases, *key) {
value.alias_set.clear();
value.alias_set.insert(alias.clone());
}
Expand Down
15 changes: 5 additions & 10 deletions rapx/src/analysis/utils/fn_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1418,16 +1418,11 @@ pub fn generate_mir_cfg_dot<'tcx>(
is_drop_related = true;
}
TerminatorKind::Call { func, .. } => {
if let Operand::Constant(c) = func {
if let ty::FnDef(def_id, _) = *c.ty().kind() {
if def_id == drop()
|| def_id == drop_in_place()
|| def_id == manually_drop()
|| dealloc_opt().map(|f| f == def_id).unwrap_or(false)
{
is_drop_related = true;
}
}
if let Operand::Constant(c) = func
&& let ty::FnDef(def_id, _) = *c.ty().kind()
&& is_drop_fn(def_id)
{
is_drop_related = true;
}
}
_ => {}
Expand Down
31 changes: 26 additions & 5 deletions rapx/src/def_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,16 @@ macro_rules! intrinsics {
($( $id:ident : $paths:expr ,)+ ) => {
const INTRINSICS: &[&[&str]] = &[$( $paths ,)+];
$(
pub fn $id() -> DefId {
${concat($id, _opt)} ().unwrap_or_else(||
panic!("Failed to retrieve the DefId of {:#?}.", $paths)
)
}
// Retrieved the fn DefId. Panic if the fn doesn't exist.
// pub fn $id() -> DefId {
// ${concat($id, _opt)} ().unwrap_or_else(||
// panic!("Failed to retrieve the DefId of {:#?}.", $paths)
// )
// }

// Retrieved the fn DefId. Returns None if the fn doesn't exist.
// This is preferred especially RAPx is used to compile nostd crates or build-std,
// where the fn is likely absent.
pub fn ${concat($id, _opt)} () -> Option<DefId> {
let map = &INIT.get().expect("Intrinsics DefIds haven't been initialized.").map;
for path in $paths {
Expand Down Expand Up @@ -168,3 +172,20 @@ intrinsics! {
pub fn to_internal<T: CrateDef>(val: &T, tcx: TyCtxt) -> DefId {
rustc_internal::internal(tcx, val.def_id())
}

/// Find any drop fn. Any of these drop fns can be missing, e.g. for crates like no_std without
/// using alloc, dealloc doesn't exist.
pub fn is_drop_fn(target: DefId) -> bool {
let drop_fn = [
drop_opt(),
drop_in_place_opt(),
manually_drop_opt(),
dealloc_opt(),
];
contains(&drop_fn, target)
}

/// Is the targe DefId in the given array.
pub fn contains(v: &[Option<DefId>], target: DefId) -> bool {
v.contains(&Some(target))
}
13 changes: 10 additions & 3 deletions rapx/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,18 @@ impl Callbacks for RapCallback {

fn after_crate_root_parsing(
&mut self,
_compiler: &interface::Compiler,
compiler: &interface::Compiler,
krate: &mut ast::Crate,
) -> Compilation {
preprocess::dummy_fns::create_dummy_fns(krate);
preprocess::ssa_preprocess::create_ssa_struct(krate);
let build_std = compiler
.sess
.opts
.crate_name
.as_deref()
.map(|s| matches!(s, "core" | "std"))
.unwrap_or(false);
preprocess::dummy_fns::create_dummy_fns(krate, build_std);
preprocess::ssa_preprocess::create_ssa_struct(krate, build_std);
Compilation::Continue
}
fn after_analysis<'tcx>(&mut self, _compiler: &Compiler, tcx: TyCtxt<'tcx>) -> Compilation {
Expand Down
10 changes: 5 additions & 5 deletions rapx/src/preprocess/dummy_fns.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::doc_attr;
use super::set_attrs;
use rustc_ast::*;
use rustc_span::{DUMMY_SP, symbol::Ident};
use thin_vec::ThinVec;
Expand Down Expand Up @@ -31,7 +31,7 @@ fn make_dummy_block() -> Block {
}
}

fn make_dummy_fn(ident_name: &str) -> Box<Item> {
fn make_dummy_fn(ident_name: &str, build_std: bool) -> Box<Item> {
let ident = Ident::from_str(ident_name);

let fn_ast = Fn {
Expand All @@ -45,7 +45,7 @@ fn make_dummy_fn(ident_name: &str) -> Box<Item> {
};

Box::new(Item {
attrs: ThinVec::from([doc_attr()]),
attrs: set_attrs(build_std),
id: DUMMY_NODE_ID,
kind: ItemKind::Fn(Box::new(fn_ast)),
vis: Visibility {
Expand All @@ -58,8 +58,8 @@ fn make_dummy_fn(ident_name: &str) -> Box<Item> {
})
}

pub(crate) fn create_dummy_fns(krate: &mut Crate) {
let raw_ptr_fn = make_dummy_fn("__raw_ptr_deref_dummy");
pub(crate) fn create_dummy_fns(krate: &mut Crate, build_std: bool) {
let raw_ptr_fn = make_dummy_fn("__raw_ptr_deref_dummy", build_std);
//let static_mut_fn = make_dummy_fn("__static_mut_deref_dummy");

krate.items.push(raw_ptr_fn);
Expand Down
54 changes: 51 additions & 3 deletions rapx/src/preprocess/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,64 @@
pub mod dummy_fns;
pub mod ssa_preprocess;

use rustc_ast::{token::CommentKind, *};
use rustc_span::{DUMMY_SP, symbol::Symbol};
use rustc_ast::{
token::{CommentKind, Delimiter, Lit, Token, TokenKind},
tokenstream::{DelimSpan, Spacing, TokenStream, TokenTree},
*,
};
use rustc_span::{DUMMY_SP, Ident, symbol::Symbol};
use thin_vec::ThinVec;

/// Empty `#[doc]` on the struct.
/// cc https://github.com/Artisan-Lab/RAPx/issues/184
pub fn doc_attr() -> Attribute {
fn doc_attr() -> Attribute {
Attribute {
kind: AttrKind::DocComment(CommentKind::Line, Symbol::intern("doc")),
id: AttrId::ZERO,
style: AttrStyle::Outer,
span: DUMMY_SP,
}
}

// #[stable(feature = "foo", since = "1.93")]
fn stability_attr() -> Attribute {
let mut attr = NormalAttr::from_ident(Ident::from_str("stable"));
let tokens: Vec<_> = {
let feature = Token::from_ast_ident(Ident::from_str("feature"));
let eq = Token::new(TokenKind::Eq, DUMMY_SP);
let feature_val = Token::new(
TokenKind::Literal(Lit::new(token::LitKind::Str, Symbol::intern("foo"), None)),
DUMMY_SP,
);
let comma = Token::new(TokenKind::Comma, DUMMY_SP);
let since = Token::from_ast_ident(Ident::from_str("since"));
let since_val = Token::new(
TokenKind::Literal(Lit::new(token::LitKind::Str, Symbol::intern("1.93"), None)),
DUMMY_SP,
);
[feature, eq, feature_val, comma, since, eq, since_val]
.into_iter()
.map(|t| TokenTree::Token(t, Spacing::Alone))
.collect()
};
attr.item.args = AttrArgs::Delimited(DelimArgs {
dspan: DelimSpan::dummy(),
delim: Delimiter::Parenthesis,
tokens: TokenStream::new(tokens),
});
Attribute {
kind: AttrKind::Normal(attr.into()),
id: AttrId::ZERO,
style: AttrStyle::Outer,
span: DUMMY_SP,
}
}

fn set_attrs(build_std: bool) -> ThinVec<Attribute> {
let mut v = ThinVec::with_capacity(2);
v.push(doc_attr());
if build_std {
v.push(stability_attr());
}
v
}
16 changes: 11 additions & 5 deletions rapx/src/preprocess/ssa_preprocess.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use super::doc_attr;
use super::set_attrs;
use rustc_ast::*;
use rustc_span::{
DUMMY_SP,
symbol::{Ident, Symbol},
};
use thin_vec::ThinVec;

pub(crate) fn create_ssa_struct(_krate: &mut Crate) {
pub(crate) fn create_ssa_struct(_krate: &mut Crate, build_std: bool) {
rap_debug!("[CALLBACK] Injecting new structs into the AST...");

let ssa_struct = create_struct(
Expand All @@ -23,6 +23,7 @@ pub(crate) fn create_ssa_struct(_krate: &mut Crate) {
("para9", Symbol::intern("i128")),
("para10", Symbol::intern("i128")),
],
build_std,
);

let essa_struct = create_struct(
Expand All @@ -32,18 +33,23 @@ pub(crate) fn create_ssa_struct(_krate: &mut Crate) {
("op2", Symbol::intern("i128")),
("cmp", Symbol::intern("i128")),
],
build_std,
);

_krate.items.push(ssa_struct);
_krate.items.push(essa_struct);

// println!("[CALLBACK] Injection complete. Continuing compilation...");
}
pub(crate) fn create_struct(name: &str, fields_def: Vec<(&str, Symbol)>) -> Box<Item> {
pub(crate) fn create_struct(
name: &str,
fields_def: Vec<(&str, Symbol)>,
build_std: bool,
) -> Box<Item> {
let fields: ThinVec<FieldDef> = fields_def
.into_iter()
.map(|(fname, fty)| FieldDef {
attrs: ThinVec::from([doc_attr()]),
attrs: set_attrs(build_std),
vis: Visibility {
span: DUMMY_SP,
kind: VisibilityKind::Public,
Expand Down Expand Up @@ -76,7 +82,7 @@ pub(crate) fn create_struct(name: &str, fields_def: Vec<(&str, Symbol)>) -> Box<
let item_kind = ItemKind::Struct(ident, Generics::default(), variant_data);

Box::new(Item {
attrs: ThinVec::from([doc_attr()]),
attrs: set_attrs(build_std),
id: NodeId::from_u32(0),
kind: item_kind,
vis: Visibility {
Expand Down
Loading