@@ -43,6 +43,7 @@ use rustc_session::config::{CrateType, OutputFilenames, OutputType};
43
43
use rustc_session:: cstore:: MetadataLoaderDyn ;
44
44
use rustc_session:: output:: out_filename;
45
45
use rustc_session:: Session ;
46
+ use rustc_smir:: rustc_internal;
46
47
use rustc_target:: abi:: Endian ;
47
48
use rustc_target:: spec:: PanicStrategy ;
48
49
use std:: any:: Any ;
@@ -208,105 +209,115 @@ impl CodegenBackend for GotocCodegenBackend {
208
209
rustc_metadata : EncodedMetadata ,
209
210
_need_metadata_module : bool ,
210
211
) -> Box < dyn Any > {
211
- super :: utils:: init ( ) ;
212
-
213
- // Queries shouldn't change today once codegen starts.
214
- let queries = self . queries . lock ( ) . unwrap ( ) . clone ( ) ;
215
- check_target ( tcx. sess ) ;
216
- check_options ( tcx. sess ) ;
217
-
218
- // Codegen all items that need to be processed according to the selected reachability mode:
219
- //
220
- // - Harnesses: Generate one model per local harnesses (marked with `kani::proof` attribute).
221
- // - Tests: Generate one model per test harnesses.
222
- // - PubFns: Generate code for all reachable logic starting from the local public functions.
223
- // - None: Don't generate code. This is used to compile dependencies.
224
- let base_filename = tcx. output_filenames ( ( ) ) . output_path ( OutputType :: Object ) ;
225
- let reachability = queries. args ( ) . reachability_analysis ;
226
- let mut results = GotoCodegenResults :: new ( tcx, reachability) ;
227
- match reachability {
228
- ReachabilityType :: Harnesses => {
229
- // Cross-crate collecting of all items that are reachable from the crate harnesses.
230
- let harnesses = queries. target_harnesses ( ) ;
231
- let mut items: HashSet < DefPathHash > = HashSet :: with_capacity ( harnesses. len ( ) ) ;
232
- items. extend ( harnesses) ;
233
- let harnesses =
234
- filter_crate_items ( tcx, |_, def_id| items. contains ( & tcx. def_path_hash ( def_id) ) ) ;
235
- for harness in harnesses {
236
- let model_path =
237
- queries. harness_model_path ( & tcx. def_path_hash ( harness. def_id ( ) ) ) . unwrap ( ) ;
212
+ let ret_val = rustc_internal:: run ( tcx, || {
213
+ super :: utils:: init ( ) ;
214
+
215
+ // Queries shouldn't change today once codegen starts.
216
+ let queries = self . queries . lock ( ) . unwrap ( ) . clone ( ) ;
217
+ check_target ( tcx. sess ) ;
218
+ check_options ( tcx. sess ) ;
219
+
220
+ // Codegen all items that need to be processed according to the selected reachability mode:
221
+ //
222
+ // - Harnesses: Generate one model per local harnesses (marked with `kani::proof` attribute).
223
+ // - Tests: Generate one model per test harnesses.
224
+ // - PubFns: Generate code for all reachable logic starting from the local public functions.
225
+ // - None: Don't generate code. This is used to compile dependencies.
226
+ let base_filename = tcx. output_filenames ( ( ) ) . output_path ( OutputType :: Object ) ;
227
+ let reachability = queries. args ( ) . reachability_analysis ;
228
+ let mut results = GotoCodegenResults :: new ( tcx, reachability) ;
229
+ match reachability {
230
+ ReachabilityType :: Harnesses => {
231
+ // Cross-crate collecting of all items that are reachable from the crate harnesses.
232
+ let harnesses = queries. target_harnesses ( ) ;
233
+ let mut items: HashSet < DefPathHash > = HashSet :: with_capacity ( harnesses. len ( ) ) ;
234
+ items. extend ( harnesses) ;
235
+ let harnesses = filter_crate_items ( tcx, |_, def_id| {
236
+ items. contains ( & tcx. def_path_hash ( def_id) )
237
+ } ) ;
238
+ for harness in harnesses {
239
+ let model_path = queries
240
+ . harness_model_path ( & tcx. def_path_hash ( harness. def_id ( ) ) )
241
+ . unwrap ( ) ;
242
+ let ( gcx, items) =
243
+ self . codegen_items ( tcx, & [ harness] , model_path, & results. machine_model ) ;
244
+ results. extend ( gcx, items, None ) ;
245
+ }
246
+ }
247
+ ReachabilityType :: Tests => {
248
+ // We're iterating over crate items here, so what we have to codegen is the "test description" containing the
249
+ // test closure that we want to execute
250
+ // TODO: Refactor this code so we can guarantee that the pair (test_fn, test_desc) actually match.
251
+ let mut descriptions = vec ! [ ] ;
252
+ let harnesses = filter_const_crate_items ( tcx, |_, def_id| {
253
+ if is_test_harness_description ( tcx, def_id) {
254
+ descriptions. push ( def_id) ;
255
+ true
256
+ } else {
257
+ false
258
+ }
259
+ } ) ;
260
+ // Codegen still takes a considerable amount, thus, we only generate one model for
261
+ // all harnesses and copy them for each harness.
262
+ // We will be able to remove this once we optimize all calls to CBMC utilities.
263
+ // https://github.com/model-checking/kani/issues/1971
264
+ let model_path = base_filename. with_extension ( ArtifactType :: SymTabGoto ) ;
238
265
let ( gcx, items) =
239
- self . codegen_items ( tcx, & [ harness ] , model_path, & results. machine_model ) ;
266
+ self . codegen_items ( tcx, & harnesses , & model_path, & results. machine_model ) ;
240
267
results. extend ( gcx, items, None ) ;
241
- }
242
- }
243
- ReachabilityType :: Tests => {
244
- // We're iterating over crate items here, so what we have to codegen is the "test description" containing the
245
- // test closure that we want to execute
246
- // TODO: Refactor this code so we can guarantee that the pair (test_fn, test_desc) actually match.
247
- let mut descriptions = vec ! [ ] ;
248
- let harnesses = filter_const_crate_items ( tcx , |_ , def_id| {
249
- if is_test_harness_description ( tcx , def_id ) {
250
- descriptions . push ( def_id ) ;
251
- true
252
- } else {
253
- false
268
+
269
+ for ( test_fn , test_desc ) in harnesses . iter ( ) . zip ( descriptions . iter ( ) ) {
270
+ let instance =
271
+ if let MonoItem :: Fn ( instance ) = test_fn { instance } else { continue } ;
272
+ let metadata =
273
+ gen_test_metadata ( tcx , * test_desc, * instance , & base_filename ) ;
274
+ let test_model_path = & metadata . goto_file . as_ref ( ) . unwrap ( ) ;
275
+ std :: fs :: copy ( & model_path , test_model_path ) . expect ( & format ! (
276
+ "Failed to copy {} to {}" ,
277
+ model_path . display ( ) ,
278
+ test_model_path . display ( )
279
+ ) ) ;
280
+ results . harnesses . push ( metadata ) ;
254
281
}
255
- } ) ;
256
- // Codegen still takes a considerable amount, thus, we only generate one model for
257
- // all harnesses and copy them for each harness.
258
- // We will be able to remove this once we optimize all calls to CBMC utilities.
259
- // https://github.com/model-checking/kani/issues/1971
260
- let model_path = base_filename. with_extension ( ArtifactType :: SymTabGoto ) ;
261
- let ( gcx, items) =
262
- self . codegen_items ( tcx, & harnesses, & model_path, & results. machine_model ) ;
263
- results. extend ( gcx, items, None ) ;
264
-
265
- for ( test_fn, test_desc) in harnesses. iter ( ) . zip ( descriptions. iter ( ) ) {
266
- let instance =
267
- if let MonoItem :: Fn ( instance) = test_fn { instance } else { continue } ;
268
- let metadata = gen_test_metadata ( tcx, * test_desc, * instance, & base_filename) ;
269
- let test_model_path = & metadata. goto_file . as_ref ( ) . unwrap ( ) ;
270
- std:: fs:: copy ( & model_path, test_model_path) . expect ( & format ! (
271
- "Failed to copy {} to {}" ,
272
- model_path. display( ) ,
273
- test_model_path. display( )
274
- ) ) ;
275
- results. harnesses . push ( metadata) ;
282
+ }
283
+ ReachabilityType :: None => { }
284
+ ReachabilityType :: PubFns => {
285
+ let entry_fn = tcx. entry_fn ( ( ) ) . map ( |( id, _) | id) ;
286
+ let local_reachable = filter_crate_items ( tcx, |_, def_id| {
287
+ ( tcx. is_reachable_non_generic ( def_id) && tcx. def_kind ( def_id) . is_fn_like ( ) )
288
+ || entry_fn == Some ( def_id)
289
+ } ) ;
290
+ let model_path = base_filename. with_extension ( ArtifactType :: SymTabGoto ) ;
291
+ let ( gcx, items) = self . codegen_items (
292
+ tcx,
293
+ & local_reachable,
294
+ & model_path,
295
+ & results. machine_model ,
296
+ ) ;
297
+ results. extend ( gcx, items, None ) ;
276
298
}
277
299
}
278
- ReachabilityType :: None => { }
279
- ReachabilityType :: PubFns => {
280
- let entry_fn = tcx. entry_fn ( ( ) ) . map ( |( id, _) | id) ;
281
- let local_reachable = filter_crate_items ( tcx, |_, def_id| {
282
- ( tcx. is_reachable_non_generic ( def_id) && tcx. def_kind ( def_id) . is_fn_like ( ) )
283
- || entry_fn == Some ( def_id)
284
- } ) ;
285
- let model_path = base_filename. with_extension ( ArtifactType :: SymTabGoto ) ;
286
- let ( gcx, items) =
287
- self . codegen_items ( tcx, & local_reachable, & model_path, & results. machine_model ) ;
288
- results. extend ( gcx, items, None ) ;
289
- }
290
- }
291
300
292
- if reachability != ReachabilityType :: None {
293
- // Print compilation report.
294
- results. print_report ( tcx) ;
295
-
296
- if reachability != ReachabilityType :: Harnesses {
297
- // In a workspace, cargo seems to be using the same file prefix to build a crate that is
298
- // a package lib and also a dependency of another package.
299
- // To avoid overriding the metadata for its verification, we skip this step when
300
- // reachability is None, even because there is nothing to record.
301
- write_file (
302
- & base_filename,
303
- ArtifactType :: Metadata ,
304
- & results. generate_metadata ( ) ,
305
- queries. args ( ) . output_pretty_json ,
306
- ) ;
301
+ if reachability != ReachabilityType :: None {
302
+ // Print compilation report.
303
+ results. print_report ( tcx) ;
304
+
305
+ if reachability != ReachabilityType :: Harnesses {
306
+ // In a workspace, cargo seems to be using the same file prefix to build a crate that is
307
+ // a package lib and also a dependency of another package.
308
+ // To avoid overriding the metadata for its verification, we skip this step when
309
+ // reachability is None, even because there is nothing to record.
310
+ write_file (
311
+ & base_filename,
312
+ ArtifactType :: Metadata ,
313
+ & results. generate_metadata ( ) ,
314
+ queries. args ( ) . output_pretty_json ,
315
+ ) ;
316
+ }
307
317
}
308
- }
309
- codegen_results ( tcx, rustc_metadata, & results. machine_model )
318
+ codegen_results ( tcx, rustc_metadata, & results. machine_model )
319
+ } ) ;
320
+ ret_val. unwrap ( )
310
321
}
311
322
312
323
fn join_codegen (
0 commit comments