https://gcc.gnu.org/g:a926ad27cda683dd32fb3a6d2c809af13d418cce

commit a926ad27cda683dd32fb3a6d2c809af13d418cce
Author: Jakub Dupak <d...@jakubdupak.com>
Date:   Wed Feb 28 00:01:28 2024 +0100

    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 819c34a93749..085b6a0b5188 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 ebfddab76170..6081a0166c10 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 1534260552b0..d94a20f98ae4 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 168b7054608d..bf9978f17010 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 ())

Reply via email to