LCOV - code coverage report
Current view: top level - gcc/rust/checks/errors/borrowck/polonius - rust-polonius-ffi.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 34 34
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 9 9
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
       2              : 
       3              : // This file is part of GCC.
       4              : 
       5              : // GCC is free software; you can redistribute it and/or modify it under
       6              : // the terms of the GNU General Public License as published by the Free
       7              : // Software Foundation; either version 3, or (at your option) any later
       8              : // version.
       9              : 
      10              : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11              : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12              : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13              : // for more details.
      14              : 
      15              : // You should have received a copy of the GNU General Public License
      16              : // along with GCC; see the file COPYING3.  If not see
      17              : // <http://www.gnu.org/licenses/>.
      18              : 
      19              : #ifndef RUST_POLONIUS_FACTS_FFI_H
      20              : #define RUST_POLONIUS_FACTS_FFI_H
      21              : 
      22              : #include "rust-system.h"
      23              : 
      24              : // This file defines the C++ side of the FFI interface to Polonius.
      25              : // The corresponding Rust side is in `gccrs-ffi.rs`.
      26              : 
      27              : // IMPORTANT:
      28              : // This file intentionally does not include any C++ headers
      29              : // to allow seamless binding generation on the Rust side.
      30              : 
      31              : namespace Rust {
      32              : namespace Polonius {
      33              : 
      34              : using Origin = size_t;
      35              : using Loan = size_t;
      36              : /**
      37              :  * Compressed CFG point
      38              :  * Encoding:
      39              :  *  - (bit size - 16) bits: basic block index
      40              :  *  - 15 bits: stmt index inside basic block
      41              :  *  - 1bit: start or mid
      42              :  *
      43              :  * Note: Polonius requires the holding type to be `size_t`/`usize`.
      44              :  */
      45              : using Point = size_t;
      46              : using Variable = size_t;
      47              : using Path = size_t;
      48              : 
      49              : namespace FFI {
      50              : 
      51              : // NOTE: std::pair and std::tuple are complicating the bindings' generation.
      52              : template <typename T1, typename T2> struct Pair
      53              : {
      54              :   T1 first;
      55              :   T2 second;
      56              : 
      57         3330 :   Pair (T1 first, T2 second) : first (first), second (second) {}
      58              : };
      59              : 
      60              : template <typename T1, typename T2, typename T3> struct Triple
      61              : {
      62              :   T1 first;
      63              :   T2 second;
      64              :   T3 third;
      65              : 
      66          368 :   Triple (T1 first, T2 second, T3 third)
      67          368 :     : first (first), second (second), third (third)
      68              :   {}
      69              : };
      70              : 
      71              : /** Frozen variant to vector for FFI */
      72              : template <typename T> struct Slice
      73              : {
      74              :   size_t len;
      75              :   const T *const data;
      76              : 
      77              :   template <typename vector>
      78           36 :   Slice (const vector &v) : len (v.size ()), data (v.data ())
      79              :   {}
      80              : };
      81              : 
      82              : /** Frozen variant of the facts with C ABI and no methods. */
      83              : struct FactsView
      84              : {
      85              :   Slice<Triple<Origin, Loan, Point>> loan_issued_at;
      86              :   Slice<Origin> universal_region;
      87              :   Slice<Pair<Point, Point>> cfg_edge;
      88              :   Slice<Pair<Loan, Point>> loan_killed_at;
      89              :   Slice<Triple<Origin, Origin, Point>> subset_base;
      90              :   Slice<Pair<Point, Loan>> loan_invalidated_at;
      91              :   Slice<Pair<Variable, Point>> var_used_at;
      92              :   Slice<Pair<Variable, Point>> var_defined_at;
      93              :   Slice<Pair<Variable, Point>> var_dropped_at;
      94              :   Slice<Pair<Variable, Origin>> use_of_var_derefs_origin;
      95              :   Slice<Pair<Variable, Origin>> drop_of_var_derefs_origin;
      96              :   Slice<Pair<Path, Path>> child_path;
      97              :   Slice<Pair<Path, Variable>> path_is_var;
      98              :   Slice<Pair<Path, Point>> path_assigned_at_base;
      99              :   Slice<Pair<Path, Point>> path_moved_at_base;
     100              :   Slice<Pair<Path, Point>> path_accessed_at_base;
     101              :   Slice<Pair<Origin, Origin>> known_placeholder_subset;
     102              :   Slice<Pair<Origin, Loan>> placeholder;
     103              : };
     104              : 
     105              : // Wrapper around std::vector to pass data from Rust to C++
     106          235 : template <typename T> struct FFIVector
     107              : {
     108              :   std::vector<T> data;
     109              : 
     110              : public:
     111           48 :   void push (T new_element) { data.push_back (new_element); };
     112              : 
     113              :   // allocates memory to a new instance and returns the pointer
     114          127 :   static FFIVector *make_new () { return new FFIVector{}; }
     115              : 
     116              :   // returns current size
     117           19 :   size_t size () const { return data.size (); }
     118              : 
     119           87 :   T at (size_t index) const
     120              :   {
     121           87 :     rust_assert (index < data.size ());
     122           87 :     return data.at (index);
     123              :   }
     124              : };
     125              : 
     126              : // Some useful type aliases
     127              : using FFIVectorPair = FFIVector<Pair<size_t, FFIVector<size_t> *>>;
     128              : using FFIVectorTriple = FFIVector<Triple<size_t, size_t, size_t>>;
     129              : 
     130              : inline std::vector<size_t>
     131           19 : make_vector (const FFIVector<size_t> *vec_sizet)
     132              : {
     133           19 :   std::vector<size_t> return_val (vec_sizet->size ());
     134           38 :   for (size_t i = 0; i < vec_sizet->size (); ++i)
     135              :     {
     136           19 :       return_val[i] = vec_sizet->at (i);
     137              :     }
     138           19 :   return return_val;
     139              : }
     140              : 
     141              : inline std::vector<std::pair<size_t, std::vector<size_t>>>
     142           72 : make_vector (const FFIVectorPair *vec_pair)
     143              : {
     144           72 :   std::vector<std::pair<size_t, std::vector<size_t>>> return_val (
     145           72 :     vec_pair->size ());
     146           91 :   for (size_t i = 0; i < vec_pair->size (); ++i)
     147              :     {
     148           19 :       std::pair<size_t, std::vector<size_t>> current_pair
     149           19 :         = {vec_pair->at (i).first, make_vector (vec_pair->at (i).second)};
     150           19 :       return_val[i] = current_pair;
     151           19 :     }
     152           72 :   return return_val;
     153              : }
     154              : 
     155              : inline std::vector<std::pair<size_t, std::pair<size_t, size_t>>>
     156           36 : make_vector (const FFIVectorTriple *vec_triple)
     157              : {
     158           36 :   std::vector<std::pair<size_t, std::pair<size_t, size_t>>> return_val (
     159           36 :     vec_triple->size ());
     160           46 :   for (size_t i = 0; i < vec_triple->size (); ++i)
     161              :     {
     162           10 :       auto current_element = std::pair<size_t, std::pair<size_t, size_t>>{
     163           10 :         vec_triple->at (i).first,
     164           10 :         {vec_triple->at (i).second, vec_triple->at (i).third}};
     165           10 :       return_val[i] = current_element;
     166              :     }
     167           36 :   return return_val;
     168              : }
     169              : 
     170              : struct Output
     171              : {
     172              :   FFIVectorPair *loan_errors;
     173              :   FFIVectorPair *move_errors;
     174              :   FFIVectorTriple *subset_errors;
     175              : };
     176              : 
     177              : } // namespace FFI
     178              : } // namespace Polonius
     179              : } // namespace Rust
     180              : 
     181              : #endif // RUST_POLONIUS_FACTS_FFI_H
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.