diff --git a/data b/data index ef00bb7..aafdd70 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit ef00bb72c1b885fa6ddc8cf98218c6983528d347 +Subproject commit aafdd706df0de038b0bcf661962fb12e0013b5bf diff --git a/run.sh b/run.sh index 5c4426a..8bbffbd 100755 --- a/run.sh +++ b/run.sh @@ -64,6 +64,15 @@ gen_data() { cp target/upg/demo/alloc data -r cp target/upg/demo/core data -r cp target/upg/demo/std data -r + + merge_unsafe_fns_json +} + +merge_unsafe_fns_json() { + pushd data + # Merge all objects by key, and sort by key. + jq -s 'add' -S core/navi/unsafe_fns.json alloc/navi/unsafe_fns.json std/navi/unsafe_fns.json >core-alloc-std_unsafe_fns.json + popd } gen_data diff --git a/src/adt.rs b/src/adt.rs index 3a81e79..f346022 100644 --- a/src/adt.rs +++ b/src/adt.rs @@ -1,7 +1,6 @@ use crate::utils::{FxHashMap, FxIndexSet, ThinVec}; use derive_more::Debug; use rustc_public::{ - CrateDef, mir::ProjectionElem, ty::{AdtDef, AdtKind}, }; diff --git a/src/output/caller.rs b/src/output/caller.rs index 76f84d8..efd826a 100644 --- a/src/output/caller.rs +++ b/src/output/caller.rs @@ -6,7 +6,7 @@ use crate::{ utils::FxIndexMap, }; use rustc_middle::ty::TyCtxt; -use rustc_public::{CrateDef, DefId, mir::Safety, rustc_internal::internal, ty::FnDef}; +use rustc_public::{CrateDef, DefId, rustc_internal::internal, ty::FnDef}; use serde::Serialize; #[derive(Debug, Serialize)] @@ -28,7 +28,7 @@ impl Caller { Caller { fn_def, meta: utils::Meta::new(fn_def, tcx), - safe: is_safe(fn_def), + safe: utils::is_safe(fn_def), callees: output_callee(info), adts: Default::default(), path: def_path(fn_def.def_id(), tcx, navi), @@ -92,14 +92,10 @@ pub fn output_callee(finfo: &FnInfo) -> FxIndexMap { for (fn_def, info) in &finfo.callees { let fn_def = *fn_def; let callee_info = CalleeInfo { - safe: is_safe(fn_def), + safe: utils::is_safe(fn_def), adt: Default::default(), }; map.insert(info.non_instance_name.clone(), callee_info); } map } - -fn is_safe(fn_def: FnDef) -> bool { - matches!(fn_def.fn_sig().value.safety, Safety::Safe) -} diff --git a/src/output/fn_.rs b/src/output/fn_.rs index f5105a4..a60f705 100644 --- a/src/output/fn_.rs +++ b/src/output/fn_.rs @@ -8,16 +8,41 @@ use rustc_public::{mir::Body, ty::FnDef}; use serde::Serialize; pub fn dump(map_fn: &FxIndexMap, tcx: TyCtxt, writer: &Writer) { + let mut unsafe_fns = FxIndexMap::::with_capacity_and_hasher( + map_fn.len() / 4, + Default::default(), + ); let mut all_fns = FxIndexSet::::with_capacity_and_hasher(map_fn.len() * 2, Default::default()); - // Collect all functions from caller and direct callees. - for (caller, info) in map_fn { - all_fns.insert(*caller); + + for (&caller, info) in map_fn { + // Collect all functions from caller and direct callees. + all_fns.insert(caller); for &fn_def in info.callees.keys() { all_fns.insert(fn_def); } + + // Collect all unsafe fns, including + // * unsafe caller + // * or safe fn with unsafe callees + let unsafe_caller = !utils::is_safe(caller); + let unsafe_callee = info.callees.keys().any(|&f| !utils::is_safe(f)); + if unsafe_caller | unsafe_callee { + let fn_name = utils::name(caller, tcx); + let kind = match (unsafe_caller, unsafe_callee) { + (true, true) => Unsafe::Both, + (true, false) => Unsafe::Caller, + (false, true) => Unsafe::Callee, + (false, false) => unreachable!(), + }; + unsafe_fns.insert(fn_name, kind); + } } + // Sort unsafe fns. + unsafe_fns.sort_unstable_keys(); + writer.dump_json("navi", "unsafe_fns", &unsafe_fns); + for fn_def in all_fns { let doc = Documentation::new(fn_def, tcx); @@ -39,6 +64,16 @@ pub fn dump(map_fn: &FxIndexMap, tcx: TyCtxt, writer: &Writer) { } } +#[derive(Debug, Serialize)] +pub enum Unsafe { + /// The function is unsafe, but no unsafe callees inside. + Caller, + /// At least one unsafe callee is called. + Callee, + /// The function is unsafe, and calles unsafe functions inside. + Both, +} + #[derive(Debug, Serialize)] pub struct Source { #[serde(flatten)] diff --git a/src/output/utils.rs b/src/output/utils.rs index 9682a89..6f4d889 100644 --- a/src/output/utils.rs +++ b/src/output/utils.rs @@ -1,6 +1,11 @@ use rustc_hir::def_id::DefId as IDefId; use rustc_middle::ty::TyCtxt; -use rustc_public::{CrateDef, rustc_internal::internal, ty::Span}; +use rustc_public::{ + CrateDef, + mir::Safety, + rustc_internal::internal, + ty::{FnDef, Span}, +}; use serde::Serialize; use crate::info_mod::crate_name; @@ -69,3 +74,8 @@ pub fn doc_internal(did: IDefId, tcx: TyCtxt) -> String { } buf } + +/// If the function is unsafe. +pub fn is_safe(fn_def: FnDef) -> bool { + matches!(fn_def.fn_sig().value.safety, Safety::Safe) +} diff --git a/ui/app/assets/css/main.css b/ui/app/assets/css/main.css index 28925b4..c91fceb 100644 --- a/ui/app/assets/css/main.css +++ b/ui/app/assets/css/main.css @@ -122,7 +122,7 @@ html, body { .upg-node, .upg-node-fn, .upg-node-unsafe-fn { - @apply text-lg font-mono whitespace-nowrap; + @apply text-lg font-mono whitespace-nowrap border border-gray-400; @variant dark { @apply bg-gray-800 text-white border-gray-100; }; @@ -141,7 +141,7 @@ html, body { .upg-node-adt-fn-kind { @apply text-gray-500 font-mono whitespace-nowrap bg-transparent; } -.upg-node-adt { @apply font-bold text-xl dark:border-gray-100/50; } +.upg-node-adt { @apply font-bold text-xl border dark:border-gray-100/50; } /* Unset bottom border if fields are connected to callees. */ .upg-node-adt-border-b-0 { @apply border-b-0; } .upg-node-adt-fn-kind { @apply text-lg border-none; } @@ -213,3 +213,6 @@ html, body { margin-bottom: 0.1rem !important; } } + +/* .fnLink { @apply font-mono; } */ +.unsafeFnLink { @apply text-red-700 dark:text-red-400 hover:font-bold hover:text-red-500 transition-colors; } diff --git a/ui/app/components/UPG.vue b/ui/app/components/UPG.vue index 25c8256..9c6889d 100644 --- a/ui/app/components/UPG.vue +++ b/ui/app/components/UPG.vue @@ -1,25 +1,27 @@ diff --git a/ui/app/components/widget/SearchFn.vue b/ui/app/components/widget/SearchFn.vue index 084a0e4..df7a918 100644 --- a/ui/app/components/widget/SearchFn.vue +++ b/ui/app/components/widget/SearchFn.vue @@ -3,7 +3,7 @@
{{ title }}
  1. - + {{ item.name }} @@ -16,15 +16,20 @@
    +