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 : #include "rust-borrow-checker.h"
20 : #include "rust-borrow-checker-diagnostics.h"
21 : #include "rust-function-collector.h"
22 : #include "rust-bir-fact-collector.h"
23 : #include "rust-bir-builder.h"
24 : #include "rust-bir-drop-analysis.h"
25 : #include "rust-bir-dump.h"
26 : #include "polonius/rust-polonius.h"
27 :
28 : namespace Rust {
29 : namespace HIR {
30 :
31 : void
32 4 : dump_function_bir (const std::string &filename, BIR::Function &func,
33 : const std::string &name)
34 : {
35 4 : std::ofstream file;
36 4 : file.open (filename);
37 4 : if (file.fail ())
38 : {
39 0 : rust_error_at (UNKNOWN_LOCATION, "Failed to open file %s",
40 : filename.c_str ());
41 0 : return;
42 : }
43 4 : BIR::Dump (file, func, name).go ();
44 4 : file.close ();
45 4 : }
46 :
47 : void
48 14 : BorrowChecker::go (HIR::Crate &crate)
49 : {
50 14 : std::string crate_name;
51 :
52 14 : BIR::DropAnalysis::get ().clear ();
53 :
54 14 : if (enable_dump_bir)
55 : {
56 1 : mkdir ("bir_dump", 0755);
57 1 : auto &mappings = Analysis::Mappings::get ();
58 1 : crate_name
59 1 : = *mappings.get_crate_name (crate.get_mappings ().get_crate_num ());
60 1 : mkdir ("nll_facts_gccrs", 0755);
61 : }
62 :
63 14 : FunctionCollector collector;
64 14 : collector.go (crate);
65 :
66 61 : for (auto func : collector.get_functions ())
67 : {
68 47 : rust_debug_loc (func->get_locus (), "\nChecking function %s\n",
69 47 : func->get_function_name ().as_string ().c_str ());
70 :
71 47 : BIR::BuilderContext ctx;
72 47 : BIR::Builder builder (ctx);
73 47 : auto bir = builder.build (*func);
74 :
75 47 : BIR::DropAnalysis::get ().analyze (bir);
76 :
77 47 : if (enable_dump_bir)
78 : {
79 8 : std::string filename = "bir_dump/" + crate_name + "."
80 12 : + func->get_function_name ().as_string ()
81 4 : + ".bir.dump";
82 4 : dump_function_bir (filename, bir,
83 8 : func->get_function_name ().as_string ());
84 4 : }
85 :
86 47 : auto facts = BIR::FactCollector::collect (bir);
87 :
88 47 : if (enable_dump_bir)
89 : {
90 4 : auto dir
91 4 : = "nll_facts_gccrs/" + func->get_function_name ().as_string ();
92 4 : mkdir (dir.c_str (), 0755);
93 4 : auto dump_facts_to_file
94 72 : = [&] (const std::string &suffix,
95 : void (Polonius::Facts::*fn) (std::ostream &) const) {
96 72 : std::string filename = "nll_facts_gccrs/"
97 144 : + func->get_function_name ().as_string ()
98 144 : + "/" + suffix + ".facts";
99 72 : std::ofstream file;
100 72 : file.open (filename);
101 72 : if (file.fail ())
102 : {
103 0 : abort ();
104 : }
105 :
106 : // Run dump
107 : // BEWARE: this callback charade is a workaround because gcc48
108 : // won't let me return a file from a function
109 72 : (facts.*fn) (file);
110 72 : };
111 :
112 4 : dump_facts_to_file ("loan_issued_at",
113 : &Polonius::Facts::dump_loan_issued_at);
114 4 : dump_facts_to_file ("loan_killed_at",
115 : &Polonius::Facts::dump_loan_killed_at);
116 4 : dump_facts_to_file ("loan_invalidated_at",
117 : &Polonius::Facts::dump_loan_invalidated_at);
118 4 : dump_facts_to_file ("subset_base",
119 : &Polonius::Facts::dump_subset_base);
120 4 : dump_facts_to_file ("universal_region",
121 : &Polonius::Facts::dump_universal_region);
122 4 : dump_facts_to_file ("cfg_edge", &Polonius::Facts::dump_cfg_edge);
123 4 : dump_facts_to_file ("var_used_at",
124 : &Polonius::Facts::dump_var_used_at);
125 4 : dump_facts_to_file ("var_defined_at",
126 : &Polonius::Facts::dump_var_defined_at);
127 4 : dump_facts_to_file ("var_dropped_at",
128 : &Polonius::Facts::dump_var_dropped_at);
129 4 : dump_facts_to_file ("use_of_var_derefs_origin",
130 : &Polonius::Facts::dump_use_of_var_derefs_origin);
131 4 : dump_facts_to_file ("drop_of_var_derefs_origin",
132 : &Polonius::Facts::dump_drop_of_var_derefs_origin);
133 4 : dump_facts_to_file ("child_path", &Polonius::Facts::dump_child_path);
134 4 : dump_facts_to_file ("path_is_var",
135 : &Polonius::Facts::dump_path_is_var);
136 4 : dump_facts_to_file ("known_placeholder_subset",
137 : &Polonius::Facts::dump_known_placeholder_subset);
138 4 : dump_facts_to_file ("path_moved_at_base",
139 : &Polonius::Facts::dump_path_moved_at_base);
140 4 : dump_facts_to_file ("path_accessed_at_base",
141 : &Polonius::Facts::dump_path_accessed_at_base);
142 4 : dump_facts_to_file ("path_assigned_at_base",
143 : &Polonius::Facts::dump_path_assigned_at_base);
144 4 : dump_facts_to_file ("placeholder",
145 : &Polonius::Facts::dump_placeholder);
146 4 : }
147 :
148 47 : auto result
149 47 : = Polonius::polonius_run (facts.freeze (), rust_be_debug_p ());
150 :
151 : // convert to std::vector variation for easier navigation
152 47 : auto loan_errors = make_vector (result.loan_errors);
153 47 : auto move_errors = make_vector (result.move_errors);
154 47 : auto subset_errors = make_vector (result.subset_errors);
155 :
156 : // free allocated data
157 94 : delete result.loan_errors;
158 94 : delete result.move_errors;
159 94 : delete result.subset_errors;
160 :
161 47 : BIR::BorrowCheckerDiagnostics (func, bir, facts, move_errors, loan_errors,
162 47 : subset_errors)
163 47 : .report_errors ();
164 47 : }
165 :
166 14 : for (auto closure ATTRIBUTE_UNUSED : collector.get_closures ())
167 0 : rust_sorry_at (closure->get_locus (),
168 : "Closure borrow checking is not implemented yet.");
169 14 : }
170 :
171 : } // namespace HIR
172 : } // namespace Rust
|