diff --git a/crates/paralegal-flow/tests/cross-crate.rs b/crates/paralegal-flow/tests/cross-crate.rs new file mode 100644 index 0000000000..bea931513f --- /dev/null +++ b/crates/paralegal-flow/tests/cross-crate.rs @@ -0,0 +1,76 @@ +#![feature(rustc_private)] +#[macro_use] +extern crate lazy_static; + +use paralegal_flow::test_utils::*; +use paralegal_spdg::Identifier; + +const CRATE_DIR: &str = "tests/cross-crate"; + +lazy_static! { + static ref TEST_CRATE_ANALYZED: bool = { + paralegal_flow_command(CRATE_DIR) + .status() + .unwrap() + .success() + }; +} + +macro_rules! define_test { + ($name:ident: $ctrl:ident -> $block:block) => { + define_test!($name: $ctrl, $name -> $block); + }; + ($name:ident: $ctrl:ident, $ctrl_name:ident -> $block:block) => { + paralegal_flow::define_flow_test_template!(TEST_CRATE_ANALYZED, CRATE_DIR, $name: $ctrl, $ctrl_name -> $block); + }; +} + +define_test!(basic : graph -> { + let src_fn = graph.function("src"); + let src = graph.call_site(&src_fn); + let not_src_fn = graph.function("not_src"); + let not_src = graph.call_site(¬_src_fn); + let target_fn = graph.function("target"); + let target = graph.call_site(&target_fn); + assert!(src.output().flows_to_data(&target.input())); + assert!(!not_src.output().flows_to_data(&target.input())); +}); + +define_test!(basic_marker: graph -> { + + let marker = Identifier::new_intern("mark"); + assert!(dbg!(&graph.spdg().markers).iter().any(|(_, markers)| markers.contains(&marker))) +}); + +define_test!(assigns_marker: graph -> { + let sources = graph.marked(Identifier::new_intern("source")); + let mark = graph.marked(Identifier::new_intern("mark")); + let target = graph.marked(Identifier::new_intern("target")); + assert!(!sources.is_empty()); + assert!(!mark.is_empty()); + assert!(!target.is_empty()); + assert!(sources.flows_to_data(&mark)); + assert!(mark.flows_to_data(&target)); +}); + +define_test!(basic_generic : graph -> { + let src_fn = graph.function("src"); + let src = graph.call_site(&src_fn); + let not_src_fn = graph.function("not_src"); + let not_src = graph.call_site(¬_src_fn); + let target_fn = graph.function("target"); + let target = graph.call_site(&target_fn); + assert!(src.output().flows_to_data(&target.input())); + assert!(!not_src.output().flows_to_data(&target.input())); +}); + +define_test!(assigns_marker_generic: graph -> { + let sources = graph.marked(Identifier::new_intern("source")); + let mark = graph.marked(Identifier::new_intern("mark")); + let target = graph.marked(Identifier::new_intern("target")); + assert!(!sources.is_empty()); + assert!(!mark.is_empty()); + assert!(!target.is_empty()); + assert!(sources.flows_to_data(&mark)); + assert!(mark.flows_to_data(&target)); +}); diff --git a/crates/paralegal-flow/tests/cross-crate/Cargo.lock b/crates/paralegal-flow/tests/cross-crate/Cargo.lock new file mode 100644 index 0000000000..6843ae0e3b --- /dev/null +++ b/crates/paralegal-flow/tests/cross-crate/Cargo.lock @@ -0,0 +1,57 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "dependency" +version = "0.0.1" +dependencies = [ + "paralegal", +] + +[[package]] +name = "entry" +version = "0.0.1" +dependencies = [ + "dependency", + "paralegal", +] + +[[package]] +name = "paralegal" +version = "0.1.0" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/crates/paralegal-flow/tests/cross-crate/Cargo.toml b/crates/paralegal-flow/tests/cross-crate/Cargo.toml new file mode 100644 index 0000000000..6e5676e925 --- /dev/null +++ b/crates/paralegal-flow/tests/cross-crate/Cargo.toml @@ -0,0 +1,2 @@ +[workspace] +members = ["dependency", "entry"] diff --git a/crates/paralegal-flow/tests/cross-crate/dependency/Cargo.toml b/crates/paralegal-flow/tests/cross-crate/dependency/Cargo.toml new file mode 100644 index 0000000000..9cd274b7d0 --- /dev/null +++ b/crates/paralegal-flow/tests/cross-crate/dependency/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "dependency" +version = "0.0.1" + +[dependencies] +paralegal = { path = "../../../../paralegal" } diff --git a/crates/paralegal-flow/tests/cross-crate/dependency/src/lib.rs b/crates/paralegal-flow/tests/cross-crate/dependency/src/lib.rs new file mode 100644 index 0000000000..194dd768be --- /dev/null +++ b/crates/paralegal-flow/tests/cross-crate/dependency/src/lib.rs @@ -0,0 +1,30 @@ +pub fn find_me(a: usize, _b: usize) -> usize { + a +} + +#[paralegal::marker(mark, return)] +pub fn source() -> usize { + 0 +} + +#[paralegal::marker(mark, return)] +fn taint_it(_: A) -> A { + unimplemented!() +} + +pub fn assign_marker(a: usize) -> usize { + taint_it(a) +} + +pub fn find_me_generic(a: A, _b: A) -> A { + a +} + +#[paralegal::marker(mark, return)] +pub fn generic_source() -> A { + unimplemented!() +} + +pub fn assign_marker_generic(a: A) -> A { + taint_it(a) +} diff --git a/crates/paralegal-flow/tests/cross-crate/entry/Cargo.toml b/crates/paralegal-flow/tests/cross-crate/entry/Cargo.toml new file mode 100644 index 0000000000..52bdc7a83f --- /dev/null +++ b/crates/paralegal-flow/tests/cross-crate/entry/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "entry" +version = "0.0.1" + +[dependencies] +dependency = { path = "../dependency" } +paralegal = { path = "../../../../paralegal" } diff --git a/crates/paralegal-flow/tests/cross-crate/entry/src/main.rs b/crates/paralegal-flow/tests/cross-crate/entry/src/main.rs new file mode 100644 index 0000000000..66f47a24c4 --- /dev/null +++ b/crates/paralegal-flow/tests/cross-crate/entry/src/main.rs @@ -0,0 +1,43 @@ +extern crate dependency; + +use dependency::{assign_marker, assign_marker_generic, find_me, find_me_generic, source}; + +#[paralegal::marker(source, return)] +fn src() -> usize { + 0 +} + +#[paralegal::marker(not_source)] +fn not_src() -> usize { + 1 +} + +#[paralegal::marker(target, arguments = [0])] +fn target(u: usize) {} + +#[paralegal::analyze] +fn basic() { + target(find_me(src(), not_src())) +} + +#[paralegal::analyze] +fn basic_marker() { + target(source()); +} + +#[paralegal::analyze] +fn assigns_marker() { + target(assign_marker(src())); +} + +#[paralegal::analyze] +fn basic_generic() { + target(find_me_generic(src(), not_src())) +} + +#[paralegal::analyze] +fn assigns_marker_generic() { + target(assign_marker_generic(src())); +} + +fn main() {}