https://gcc.gnu.org/g:8f583ddd1e3fef9ff0d92d46f6f353411191f915
commit r15-8097-g8f583ddd1e3fef9ff0d92d46f6f353411191f915 Author: Jakub Dupak <d...@jakubdupak.com> Date: Wed Feb 28 00:01:28 2024 +0100 gccrs: borrowck: Polonius error reporting gcc/rust/ChangeLog: * checks/errors/borrowck/ffi-polonius/src/gccrs_ffi_generated.rs: Error reporting. * checks/errors/borrowck/ffi-polonius/src/lib.rs: Error reporting. * checks/errors/borrowck/polonius/rust-polonius-ffi.h (struct FactsView): Error reporting. (struct Output): Error reporting. * checks/errors/borrowck/polonius/rust-polonius.h (struct Facts): Error reporting. * checks/errors/borrowck/rust-borrow-checker.cc: Error reporting. Signed-off-by: Jakub Dupak <d...@jakubdupak.com> Diff: --- .../ffi-polonius/src/gccrs_ffi_generated.rs | 8 ++ .../checks/errors/borrowck/ffi-polonius/src/lib.rs | 115 +++++++++++++++------ .../errors/borrowck/polonius/rust-polonius-ffi.h | 7 ++ .../errors/borrowck/polonius/rust-polonius.h | 3 +- .../checks/errors/borrowck/rust-borrow-checker.cc | 21 +++- 5 files changed, 117 insertions(+), 37 deletions(-) diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi_generated.rs b/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi_generated.rs index 209081795289..db75a1d1509d 100644 --- a/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi_generated.rs +++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi_generated.rs @@ -48,3 +48,11 @@ pub struct FactsView { pub known_placeholder_subset: Slice<Pair<Origin, Origin>>, pub placeholder: Slice<Pair<Origin, Loan>>, } + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Output { + pub loan_errors: bool, + pub subset_errors: bool, + pub move_errors: bool, +} diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/src/lib.rs b/gcc/rust/checks/errors/borrowck/ffi-polonius/src/lib.rs index 99b7709d6290..b743be2e6be6 100644 --- a/gcc/rust/checks/errors/borrowck/ffi-polonius/src/lib.rs +++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/src/lib.rs @@ -86,48 +86,95 @@ fn print_point(point: GccrsAtom) { let val: usize = point.into(); let mid = val % 2 == 1; let bb = val >> 16; - let stmt = (val >> 1) & 0xFFFF; - print!("{}(bb{}[{}])", if mid { "Mid" } else { "Start" }, bb, stmt); + let stmt = (val >> 1) & ((1 << 15) - 1); + eprint!("{}(bb{}[{}])", if mid { "Mid" } else { "Start" }, bb, stmt); } /// Run the polonius analysis on the given facts (for a single function). /// Right now, results are only printed and not propagated back to the gccrs. #[no_mangle] -pub unsafe extern "C" fn polonius_run(input: gccrs_ffi::FactsView, dump_enabled: bool) { +pub unsafe extern "C" fn polonius_run( + input: gccrs_ffi::FactsView, + dump_enabled: bool, +) -> gccrs_ffi::Output { let facts = AllFacts::<GccrsFacts>::from(input); - let output = Output::compute(&facts, polonius_engine::Algorithm::Naive, dump_enabled); - - // FIXME: Temporary output - println!("Polonius analysis completed. Results:"); - println!("Errors: {:#?}", output.errors); - println!("Subset error: {:#?}", output.subset_errors); - println!("Move error: {:#?}", output.move_errors); - - println!("Subsets:"); - let mut subset_vec: Vec<_> = output.subset.iter().collect(); - subset_vec.sort_by_key(|&(point, _)| point); - for (point, subsets) in subset_vec { - print_point(*point); - println!(": {{"); - for (&lhs, rhss) in subsets { - for &rhs in rhss { - println!(" {} <= {}", usize::from(lhs), usize::from(rhs)); + let output = Output::compute( + &facts, + polonius_engine::Algorithm::DatafrogOpt, + dump_enabled, + ); + + if dump_enabled { + eprintln!("Subsets:"); + let mut subset_vec: Vec<_> = output.subset.iter().collect(); + subset_vec.sort_by_key(|&(point, _)| point); + for (point, subsets) in subset_vec { + print_point(*point); + eprintln!(": {{"); + for (&lhs, rhss) in subsets { + for &rhs in rhss { + eprintln!(" {} <= {}", usize::from(lhs), usize::from(rhs)); + } } + eprintln!("}}"); } - println!("}}"); - } - println!("Subset anywhere: {:#?}", output.subset_anywhere); - - // Print origin live on entry - println!("Origin live on entry:"); - let mut origin_vec: Vec<_> = output.origin_live_on_entry.iter().collect(); - origin_vec.sort_by_key(|&(point, _)| point); - for (point, origins) in origin_vec { - print_point(*point); - println!(": {{"); - for &origin in origins { - println!(" {}", usize::from(origin)); + + // Print origin live on entry + eprintln!("Origin live on entry:"); + let mut origin_vec: Vec<_> = output.origin_live_on_entry.iter().collect(); + origin_vec.sort_by_key(|&(point, _)| point); + for (point, origins) in origin_vec { + print_point(*point); + eprintln!(": {{"); + for &origin in origins { + eprintln!(" {}", usize::from(origin)); + } + eprintln!("}}"); + } + + eprintln!("Origin contains loan at:"); + let mut origin_vec: Vec<_> = output.origin_contains_loan_at.iter().collect(); + origin_vec.sort_by_key(|&(point, _)| point); + for (point, origins) in origin_vec { + print_point(*point); + eprintln!(": {{"); + for (&origin, loans) in origins { + eprintln!( + " {}:{:?}", + usize::from(origin), + loans.iter().map(|&e| usize::from(e)).collect::<Vec<_>>() + ); + } + eprintln!("}}"); + } + + eprintln!("Polonius analysis completed. Results:"); + if output.errors.len() > 0 { + eprintln!("Errors:"); + for (&point, errors) in &output.errors { + print_point(point); + eprintln!(": {:?}", errors); + } + } + if output.subset_errors.len() > 0 { + eprintln!("Subset errors:"); + for (&point, errors) in &output.subset_errors { + print_point(point); + eprintln!(": {:?}", errors); + } + } + if output.move_errors.len() > 0 { + eprintln!("Move errors:"); + for (&point, moves) in &output.move_errors { + print_point(point); + eprintln!("{:?}", moves); + } } - println!("}}"); } + + return gccrs_ffi::Output { + loan_errors: output.errors.len() > 0, + subset_errors: output.subset_errors.len() > 0, + move_errors: output.move_errors.len() > 0, + }; } diff --git a/gcc/rust/checks/errors/borrowck/polonius/rust-polonius-ffi.h b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius-ffi.h index 3ed8e516daee..af37e0f9fb4a 100644 --- a/gcc/rust/checks/errors/borrowck/polonius/rust-polonius-ffi.h +++ b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius-ffi.h @@ -102,6 +102,13 @@ struct FactsView Slice<Pair<Origin, Loan>> placeholder; }; +struct Output +{ + bool loan_errors; + bool subset_errors; + bool move_errors; +}; + } // namespace FFI } // namespace Polonius } // namespace Rust diff --git a/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h index b93906cdfc16..bc145e707d30 100644 --- a/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h +++ b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h @@ -28,7 +28,6 @@ namespace Rust { namespace Polonius { -/** A point in the control flow graph. */ struct FullPoint { uint32_t bb; @@ -223,7 +222,7 @@ struct Facts * * Output is not yet implemented and is only dumped to stdout. */ -extern "C" void +extern "C" FFI::Output polonius_run (FFI::FactsView input, bool dump_enabled); } // namespace Polonius diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc index 12334b11dd7d..9a75271cdae0 100644 --- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc +++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc @@ -155,7 +155,26 @@ BorrowChecker::go (HIR::Crate &crate) &Polonius::Facts::dump_placeholder); } - Polonius::polonius_run (facts.freeze (), rust_be_debug_p ()); + auto result + = Polonius::polonius_run (facts.freeze (), rust_be_debug_p ()); + + if (result.loan_errors) + { + rust_error_at (func->get_locus (), "Found loan errors in function %s", + func->get_function_name ().as_string ().c_str ()); + } + if (result.subset_errors) + { + rust_error_at (func->get_locus (), + "Found subset errors in function %s. Some lifetime " + "constraints need to be added.", + func->get_function_name ().as_string ().c_str ()); + } + if (result.move_errors) + { + rust_error_at (func->get_locus (), "Found move errors in function %s", + func->get_function_name ().as_string ().c_str ()); + } } for (auto closure ATTRIBUTE_UNUSED : collector.get_closures ())