-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gcc/rust/ChangeLog: * Make-lang.in: Build FFI-Polonius. * checks/errors/borrowck/rust-borrow-checker.cc (BorrowChecker::go): Invoke Polonius. * checks/errors/borrowck/ffi-polonius/Cargo.toml: New file. * checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs: New file. * checks/errors/borrowck/ffi-polonius/src/lib.rs: New file. * checks/errors/borrowck/polonius/rust-polonius-ffi.h: New file. * checks/errors/borrowck/polonius/rust-polonius.h: New file. Signed-off-by: Jakub Dupak <[email protected]>
- Loading branch information
Showing
7 changed files
with
432 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "ffi-polonius" | ||
version = "0.1.0" | ||
edition = "2021" | ||
license = "GPL-3" | ||
|
||
[lib] | ||
crate-type = ["staticlib"] | ||
|
||
[dependencies] | ||
polonius-engine = "0.13.0" |
115 changes: 115 additions & 0 deletions
115
gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// Copyright (C) 2023 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/>. | ||
|
||
// This is an FFI interface to gccrs (c++). | ||
// It is a counterpart to `rust-polonius-ffi.h`. | ||
|
||
// Generated by rust-bindgen, remove unsafe phantoms and add Into impls. | ||
// ```shell | ||
// bindgen \ | ||
// --generate types \ | ||
// --allowlist-file rust-polonius-facts-ffi.h \ | ||
// --no-layout-tests \ | ||
// rust-polonius-ffi.h \ | ||
// -- -x c++ | ||
// ``` | ||
|
||
// GENERATED START ============================================================ | ||
|
||
use crate::GccrsAtom; | ||
|
||
pub type Origin = usize; | ||
pub type Loan = usize; | ||
pub type Point = usize; | ||
pub type Variable = usize; | ||
pub type Path = usize; | ||
|
||
#[repr(C)] | ||
#[derive(Debug, Copy, Clone)] | ||
pub struct Pair<T1, T2> { | ||
pub first: T1, | ||
pub second: T2, | ||
} | ||
|
||
#[repr(C)] | ||
#[derive(Debug, Copy, Clone)] | ||
pub struct Triple<T1, T2, T3> { | ||
pub first: T1, | ||
pub second: T2, | ||
pub third: T3, | ||
} | ||
|
||
#[repr(C)] | ||
#[derive(Debug, Copy, Clone)] | ||
pub struct Slice<T> { | ||
pub len: u64, | ||
pub data: *const T, | ||
} | ||
|
||
#[repr(C)] | ||
#[derive(Debug, Copy, Clone)] | ||
pub struct FactsView { | ||
pub loan_issued_at: Slice<Triple<Origin, Loan, Point>>, | ||
pub universal_region: Slice<Origin>, | ||
pub cfg_edge: Slice<Pair<Point, Point>>, | ||
pub loan_killed_at: Slice<Pair<Loan, Point>>, | ||
pub subset_base: Slice<Triple<Origin, Origin, Point>>, | ||
pub loan_invalidated_at: Slice<Pair<Point, Loan>>, | ||
pub var_used_at: Slice<Pair<Variable, Point>>, | ||
pub var_defined_at: Slice<Pair<Variable, Point>>, | ||
pub var_dropped_at: Slice<Pair<Variable, Point>>, | ||
pub use_of_var_derefs_origin: Slice<Pair<Variable, Origin>>, | ||
pub drop_of_var_derefs_origin: Slice<Pair<Variable, Origin>>, | ||
pub child_path: Slice<Pair<Path, Path>>, | ||
pub path_is_var: Slice<Pair<Path, Variable>>, | ||
pub path_assigned_at_base: Slice<Pair<Path, Point>>, | ||
pub path_moved_at_base: Slice<Pair<Path, Point>>, | ||
pub path_accessed_at_base: Slice<Pair<Path, Point>>, | ||
pub known_placeholder_subset: Slice<Pair<Origin, Origin>>, | ||
pub placeholder: Slice<Pair<Origin, Loan>>, | ||
} | ||
|
||
// GENERATED END ============================================================== | ||
|
||
impl<T1, T2> Into<(GccrsAtom, GccrsAtom)> for Pair<T1, T2> | ||
where | ||
GccrsAtom: From<T1> + From<T2>, | ||
{ | ||
fn into(self) -> (GccrsAtom, GccrsAtom) { | ||
(self.first.into(), self.second.into()) | ||
} | ||
} | ||
|
||
impl<T1, T2, T3> Into<(GccrsAtom, GccrsAtom, GccrsAtom)> for Triple<T1, T2, T3> | ||
where | ||
GccrsAtom: From<T1> + From<T2> + From<T3>, | ||
{ | ||
fn into(self) -> (GccrsAtom, GccrsAtom, GccrsAtom) { | ||
(self.first.into(), self.second.into(), self.third.into()) | ||
} | ||
} | ||
|
||
impl<OUT, IN> Into<Vec<OUT>> for Slice<IN> | ||
where | ||
IN: Into<OUT> + Copy, | ||
{ | ||
fn into(self) -> Vec<OUT> { | ||
let slice = unsafe { std::slice::from_raw_parts(self.data, self.len as usize) }; | ||
slice.iter().map(|&e| e.into()).collect() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright (C) 2023 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/>. | ||
|
||
mod gccrs_ffi; | ||
|
||
use polonius_engine::{AllFacts, Atom, FactTypes, Output}; | ||
use std::fmt::Debug; | ||
use std::hash::Hash; | ||
|
||
/// A single fact value. | ||
/// For simplicity we use one type for all facts. | ||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
struct GccrsAtom(usize); | ||
|
||
impl Atom for GccrsAtom { | ||
fn index(self) -> usize { | ||
self.0 | ||
} | ||
} | ||
|
||
impl From<usize> for GccrsAtom { | ||
fn from(inner: usize) -> GccrsAtom { | ||
GccrsAtom(inner) | ||
} | ||
} | ||
|
||
impl From<GccrsAtom> for usize { | ||
fn from(atom: GccrsAtom) -> Self { | ||
atom.index() | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone, Copy, Default)] | ||
struct GccrsFacts; | ||
|
||
impl FactTypes for GccrsFacts { | ||
type Origin = GccrsAtom; | ||
type Loan = GccrsAtom; | ||
type Point = GccrsAtom; | ||
type Variable = GccrsAtom; | ||
type Path = GccrsAtom; | ||
} | ||
|
||
impl From<gccrs_ffi::FactsView> for AllFacts<GccrsFacts> { | ||
fn from(input: gccrs_ffi::FactsView) -> Self { | ||
AllFacts::<GccrsFacts> { | ||
loan_issued_at: input.loan_issued_at.into(), | ||
universal_region: input.universal_region.into(), | ||
cfg_edge: input.cfg_edge.into(), | ||
loan_killed_at: input.loan_killed_at.into(), | ||
subset_base: input.subset_base.into(), | ||
loan_invalidated_at: input.loan_invalidated_at.into(), | ||
var_used_at: input.var_used_at.into(), | ||
var_defined_at: input.var_defined_at.into(), | ||
var_dropped_at: input.var_dropped_at.into(), | ||
use_of_var_derefs_origin: input.use_of_var_derefs_origin.into(), | ||
drop_of_var_derefs_origin: input.drop_of_var_derefs_origin.into(), | ||
child_path: input.child_path.into(), | ||
path_is_var: input.path_is_var.into(), | ||
path_assigned_at_base: input.path_assigned_at_base.into(), | ||
path_moved_at_base: input.path_moved_at_base.into(), | ||
path_accessed_at_base: input.path_accessed_at_base.into(), | ||
known_placeholder_subset: input.known_placeholder_subset.into(), | ||
placeholder: input.placeholder.into(), | ||
} | ||
} | ||
} | ||
|
||
/// 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) { | ||
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); | ||
} |
98 changes: 98 additions & 0 deletions
98
gcc/rust/checks/errors/borrowck/polonius/rust-polonius-ffi.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Copyright (C) 2023 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/>. | ||
|
||
#ifndef RUST_POLONIUS_FACTS_FFI_H | ||
#define RUST_POLONIUS_FACTS_FFI_H | ||
|
||
// This file defines the C++ side of the FFI interface to Polonius. | ||
// The corresponding Rust side is in `gccrs-ffi.rs`. | ||
|
||
// IMPORTANT: | ||
// This file intentionally does not include any C++ headers | ||
// to allow seamless binding generation on the Rust side. | ||
|
||
#include <cstdint> | ||
|
||
namespace Rust { | ||
namespace Polonius { | ||
|
||
using Origin = size_t; | ||
using Loan = size_t; | ||
using Point = size_t; | ||
using Variable = size_t; | ||
using Path = size_t; | ||
|
||
namespace FFI { | ||
|
||
// NOTE: std::pair and std::tuple are complicating the bindings' generation. | ||
template <typename T1, typename T2> struct Pair | ||
{ | ||
T1 first; | ||
T2 second; | ||
|
||
Pair (T1 first, T2 second) : first (first), second (second) {} | ||
}; | ||
|
||
template <typename T1, typename T2, typename T3> struct Triple | ||
{ | ||
T1 first; | ||
T2 second; | ||
T3 third; | ||
|
||
Triple (T1 first, T2 second, T3 third) | ||
: first (first), second (second), third (third) | ||
{} | ||
}; | ||
|
||
template <typename T> struct Slice | ||
{ | ||
uint64_t len; | ||
const T *const data; | ||
|
||
template <typename vector> | ||
Slice (const vector &v) : len (v.size ()), data (v.data ()) | ||
{} | ||
}; | ||
|
||
struct FactsView | ||
{ | ||
Slice<Triple<Origin, Loan, Point>> loan_issued_at; | ||
Slice<Origin> universal_region; | ||
Slice<Pair<Point, Point>> cfg_edge; | ||
Slice<Pair<Loan, Point>> loan_killed_at; | ||
Slice<Triple<Origin, Origin, Point>> subset_base; | ||
Slice<Pair<Point, Loan>> loan_invalidated_at; | ||
Slice<Pair<Variable, Point>> var_used_at; | ||
Slice<Pair<Variable, Point>> var_defined_at; | ||
Slice<Pair<Variable, Point>> var_dropped_at; | ||
Slice<Pair<Variable, Origin>> use_of_var_derefs_origin; | ||
Slice<Pair<Variable, Origin>> drop_of_var_derefs_origin; | ||
Slice<Pair<Path, Path>> child_path; | ||
Slice<Pair<Path, Variable>> path_is_var; | ||
Slice<Pair<Path, Point>> path_assigned_at_base; | ||
Slice<Pair<Path, Point>> path_moved_at_base; | ||
Slice<Pair<Path, Point>> path_accessed_at_base; | ||
Slice<Pair<Origin, Origin>> known_placeholder_subset; | ||
Slice<Pair<Origin, Loan>> placeholder; | ||
}; | ||
|
||
} // namespace FFI | ||
} // namespace Polonius | ||
} // namespace Rust | ||
|
||
#endif // RUST_POLONIUS_FACTS_FFI_H |
Oops, something went wrong.