aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in7
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs5
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi_generated.rs6
-rw-r--r--gcc/rust/checks/errors/borrowck/ffi-polonius/src/lib.rs76
-rw-r--r--gcc/rust/checks/errors/borrowck/polonius/rust-polonius-ffi.h71
-rw-r--r--gcc/rust/checks/errors/borrowck/polonius/rust-polonius.cc66
-rw-r--r--gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h24
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc16
8 files changed, 258 insertions, 13 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 4f164c9..17f1feb 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -171,6 +171,7 @@ GRS_OBJS = \
rust/rust-borrow-checker.o \
rust/rust-bir-builder-expr-stmt.o \
rust/rust-bir-dump.o \
+ rust/rust-polonius.o\
rust/rust-hir-dot-operator.o \
rust/rust-hir-path-probe.o \
rust/rust-type-util.o \
@@ -487,6 +488,12 @@ rust/%.o: rust/checks/errors/borrowck/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
+
+# build borrow checking pass polonius files in rust folder
+rust/%.o: rust/checks/errors/borrowck/polonius/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
# build rust/metadata files in rust folder
rust/%.o: rust/metadata/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs b/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs
index 6d30d3c..0cb85078 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs
@@ -32,6 +32,11 @@ include!("gccrs_ffi_generated.rs");
use crate::GccrsAtom;
+// Using opqaue types
+extern "C" {
+ pub type FFIVector;
+}
+
impl<T1, T2> Into<(GccrsAtom, GccrsAtom)> for Pair<T1, T2>
where
GccrsAtom: From<T1> + From<T2>,
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 db75a1d..b2c190d 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
@@ -52,7 +52,7 @@ pub struct FactsView {
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Output {
- pub loan_errors: bool,
- pub subset_errors: bool,
- pub move_errors: bool,
+ pub loan_errors: *mut FFIVector,
+ pub move_errors: *mut FFIVector,
+ pub subset_errors: *mut FFIVector,
}
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 b743be2e..782a63f 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/src/lib.rs
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/src/lib.rs
@@ -16,13 +16,30 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#![feature(extern_types)]
+
mod gccrs_ffi;
-mod gccrs_ffi_generated;
+use gccrs_ffi::FFIVector;
use polonius_engine::{AllFacts, Atom, FactTypes, Output};
use std::fmt::Debug;
use std::hash::Hash;
+extern "C" {
+ fn FFIVector__new() -> *mut FFIVector;
+ fn FFIVector__new_vec_pair() -> *mut FFIVector;
+ fn FFIVector__new_vec_triple() -> *mut FFIVector;
+ fn FFIVector__push(vector: *mut FFIVector, element: usize);
+ fn FFIVector__push_vec_pair(
+ vector: *mut FFIVector,
+ element: gccrs_ffi::Pair<usize, *mut FFIVector>,
+ );
+ fn FFIVector__push_vec_triple(
+ vector: *mut FFIVector,
+ element: gccrs_ffi::Triple<usize, usize, usize>,
+ );
+}
+
/// A single fact value.
/// For simplicity we use one type for all facts.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -46,6 +63,12 @@ impl From<GccrsAtom> for usize {
}
}
+impl From<&GccrsAtom> for usize {
+ fn from(atom: &GccrsAtom) -> Self {
+ atom.index()
+ }
+}
+
#[derive(Debug, Clone, Copy, Default)]
struct GccrsFacts;
@@ -172,9 +195,54 @@ pub unsafe extern "C" fn polonius_run(
}
}
+ let loan_errors = FFIVector__new_vec_pair();
+ for (keys, values) in output.errors.iter() {
+ let loans_vec = FFIVector__new();
+ for loan in values.iter() {
+ let loan: usize = loan.into();
+ FFIVector__push(loans_vec, loan);
+ }
+ let point: usize = keys.into();
+ let pair = gccrs_ffi::Pair {
+ first: point,
+ second: loans_vec,
+ };
+ FFIVector__push_vec_pair(loan_errors, pair);
+ }
+
+ let move_errors = FFIVector__new_vec_pair();
+ for (keys, values) in output.move_errors.iter() {
+ let paths_vec = FFIVector__new();
+ for path in values.iter() {
+ let path: usize = path.into();
+ FFIVector__push(paths_vec, path);
+ }
+ let point: usize = keys.into();
+ let pair = gccrs_ffi::Pair {
+ first: point,
+ second: paths_vec,
+ };
+ FFIVector__push_vec_pair(move_errors, pair);
+ }
+
+ let subset_errors = FFIVector__new_vec_triple();
+ for (key, value) in output.subset_errors.iter() {
+ let point: usize = key.into();
+ for origin_pair in value.iter() {
+ let origin_1: usize = origin_pair.0.into();
+ let origin_2: usize = origin_pair.1.into();
+ let triple = gccrs_ffi::Triple {
+ first: point,
+ second: origin_1,
+ third: origin_2,
+ };
+ FFIVector__push_vec_triple(subset_errors, triple);
+ }
+ }
+
return gccrs_ffi::Output {
- loan_errors: output.errors.len() > 0,
- subset_errors: output.subset_errors.len() > 0,
- move_errors: output.move_errors.len() > 0,
+ loan_errors,
+ move_errors,
+ subset_errors,
};
}
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 af37e0f..e11ba55 100644
--- a/gcc/rust/checks/errors/borrowck/polonius/rust-polonius-ffi.h
+++ b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius-ffi.h
@@ -102,11 +102,76 @@ struct FactsView
Slice<Pair<Origin, Loan>> placeholder;
};
+// Wrapper around std::vector to pass data from Rust to C++
+template <typename T> struct FFIVector
+{
+ std::vector<T> data;
+
+public:
+ void push (T new_element) { data.push_back (new_element); };
+
+ // allocates memory to a new instance and returns the pointer
+ static FFIVector *make_new () { return new FFIVector{}; }
+
+ // returns current size
+ size_t size () const { return data.size (); }
+
+ T at (size_t index) const
+ {
+ rust_assert (index < data.size ());
+ return data.at (index);
+ }
+};
+
+// Some useful type aliases
+using FFIVectorPair = FFIVector<Pair<size_t, FFIVector<size_t> *>>;
+using FFIVectorTriple = FFIVector<Triple<size_t, size_t, size_t>>;
+
+inline std::vector<size_t>
+make_vector (const FFIVector<size_t> *vec_sizet)
+{
+ std::vector<size_t> return_val (vec_sizet->size ());
+ for (size_t i = 0; i < vec_sizet->size (); ++i)
+ {
+ return_val[i] = vec_sizet->at (i);
+ }
+ return return_val;
+}
+
+inline std::vector<std::pair<size_t, std::vector<size_t>>>
+make_vector (const FFIVectorPair *vec_pair)
+{
+ std::vector<std::pair<size_t, std::vector<size_t>>> return_val (
+ vec_pair->size ());
+ for (size_t i = 0; i < vec_pair->size (); ++i)
+ {
+ std::pair<size_t, std::vector<size_t>> current_pair
+ = {vec_pair->at (i).first, make_vector (vec_pair->at (i).second)};
+ return_val[i] = current_pair;
+ }
+ return return_val;
+}
+
+inline std::vector<std::pair<size_t, std::pair<size_t, size_t>>>
+make_vector (const FFIVectorTriple *vec_triple)
+{
+ std::vector<std::pair<size_t, std::pair<size_t, size_t>>> return_val (
+ vec_triple->size ());
+ for (size_t i = 0; i < vec_triple->size (); ++i)
+ {
+ auto current_element = std::pair<size_t, std::pair<size_t, size_t>>{
+ vec_triple->at (i).first,
+ {vec_triple->at (i).second, vec_triple->at (i).third}};
+ return_val[i] = current_element;
+ }
+ return return_val;
+}
+
struct Output
{
- bool loan_errors;
- bool subset_errors;
- bool move_errors;
+ FFIVectorPair *loan_errors;
+ FFIVectorPair *move_errors;
+ FFIVectorTriple *subset_errors;
};
} // namespace FFI
diff --git a/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.cc b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.cc
new file mode 100644
index 0000000..61f431f
--- /dev/null
+++ b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.cc
@@ -0,0 +1,66 @@
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-polonius.h"
+
+namespace Rust {
+namespace Polonius {
+
+extern "C" {
+
+FFI::FFIVector<size_t> *
+FFIVector__new ()
+{
+ return FFI::FFIVector<size_t>::make_new ();
+}
+
+FFI::FFIVectorPair *
+FFIVector__new_vec_pair ()
+{
+ return FFI::FFIVectorPair::make_new ();
+}
+
+FFI::FFIVectorTriple *
+FFIVector__new_vec_triple ()
+{
+ return FFI::FFIVectorTriple::make_new ();
+}
+
+void
+FFIVector__push (FFI::FFIVector<size_t> *vector, size_t element)
+{
+ vector->push (element);
+}
+
+void
+FFIVector__push_vec_pair (FFI::FFIVectorPair *vector,
+ FFI::Pair<size_t, FFI::FFIVector<size_t> *> element)
+{
+ vector->push (element);
+}
+
+void
+FFIVector__push_vec_triple (FFI::FFIVectorTriple *vector,
+ FFI::Triple<size_t, size_t, size_t> element)
+{
+ vector->push (element);
+}
+}
+
+} // 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 bc145e7..b013a93 100644
--- a/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h
+++ b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h
@@ -225,6 +225,30 @@ struct Facts
extern "C" FFI::Output
polonius_run (FFI::FactsView input, bool dump_enabled);
+// Helper functions for FFIVector to be used on Rust side
+extern "C" {
+
+FFI::FFIVector<size_t> *
+FFIVector__new ();
+
+FFI::FFIVectorPair *
+FFIVector__new_vec_pair ();
+
+FFI::FFIVectorTriple *
+FFIVector__new_vec_triple ();
+
+void
+FFIVector__push (FFI::FFIVector<size_t> *vector, size_t element);
+
+void
+FFIVector__push_vec_pair (FFI::FFIVectorPair *vector,
+ FFI::Pair<size_t, FFI::FFIVector<size_t> *> element);
+
+void
+FFIVector__push_vec_triple (FFI::FFIVectorTriple *vector,
+ FFI::Triple<size_t, size_t, size_t> element);
+}
+
} // namespace Polonius
} // namespace Rust
diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
index 29a9f4d..0ef4e5a 100644
--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
@@ -142,19 +142,29 @@ BorrowChecker::go (HIR::Crate &crate)
auto result
= Polonius::polonius_run (facts.freeze (), rust_be_debug_p ());
- if (result.loan_errors)
+ // convert to std::vector variation for easier navigation
+ auto loan_errors = make_vector (result.loan_errors);
+ auto move_errors = make_vector (result.move_errors);
+ auto subset_errors = make_vector (result.subset_errors);
+
+ // free allocated data
+ delete result.loan_errors;
+ delete result.move_errors;
+ delete result.subset_errors;
+
+ if (!loan_errors.empty ())
{
rust_error_at (func->get_locus (), "Found loan errors in function %s",
func->get_function_name ().as_string ().c_str ());
}
- if (result.subset_errors)
+ if (!subset_errors.empty ())
{
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)
+ if (!move_errors.empty ())
{
rust_error_at (func->get_locus (), "Found move errors in function %s",
func->get_function_name ().as_string ().c_str ());