diff options
Diffstat (limited to 'gcc')
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 ()); |