From 24ee5069134e6ee6b88487f229cd05e383e1a314 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sun, 27 May 2018 22:26:10 +0100 Subject: [PATCH] Ensure that depth first search does not get stuck in cycles. --- src/librustc_mir/dataflow/impls/borrows.rs | 40 +++++++++++++++------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index ed111c994f41a..317b62b22dc3a 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -59,9 +59,16 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>( borrows_out_of_scope_at_location: &mut FxHashMap>, borrow_index: BorrowIndex, borrow_region: RegionVid, - location: Location + location: Location, + visited_locations: &mut Vec ) { - // Start by dealing with the current location. + // Check if we have already visited this location and skip + // it if we have - avoids infinite loops. + if visited_locations.contains(&location) { return; } + visited_locations.push(location.clone()); + + // Next, add the borrow index to the current location's vector if the region does + // not contain the point at that location (or create a new vector if required). if !regioncx.region_contains_point(borrow_region, location) { borrows_out_of_scope_at_location .entry(location.clone()) @@ -80,14 +87,16 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>( TerminatorKind::FalseUnwind { real_target: target, .. } => { precompute_borrows_out_of_scope( mir, regioncx, borrows_out_of_scope_at_location, - borrow_index, borrow_region, target.start_location() + borrow_index, borrow_region, target.start_location(), + visited_locations ); }, TerminatorKind::SwitchInt { ref targets, .. } => { for block in targets { precompute_borrows_out_of_scope( mir, regioncx, borrows_out_of_scope_at_location, - borrow_index, borrow_region, block.start_location() + borrow_index, borrow_region, block.start_location(), + visited_locations ); } }, @@ -95,13 +104,15 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>( TerminatorKind::DropAndReplace { target, unwind, .. } => { precompute_borrows_out_of_scope( mir, regioncx, borrows_out_of_scope_at_location, - borrow_index, borrow_region, target.start_location() + borrow_index, borrow_region, target.start_location(), + visited_locations ); if let Some(unwind_block) = unwind { precompute_borrows_out_of_scope( mir, regioncx, borrows_out_of_scope_at_location, - borrow_index, borrow_region, unwind_block.start_location() + borrow_index, borrow_region, unwind_block.start_location(), + visited_locations ); } }, @@ -109,14 +120,16 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>( if let Some((_, block)) = destination { precompute_borrows_out_of_scope( mir, regioncx, borrows_out_of_scope_at_location, - borrow_index, borrow_region, block.start_location() + borrow_index, borrow_region, block.start_location(), + visited_locations ); } if let Some(block) = cleanup { precompute_borrows_out_of_scope( mir, regioncx, borrows_out_of_scope_at_location, - borrow_index, borrow_region, block.start_location() + borrow_index, borrow_region, block.start_location(), + visited_locations ); } }, @@ -124,13 +137,15 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>( TerminatorKind::Yield { resume: target, drop: cleanup, .. } => { precompute_borrows_out_of_scope( mir, regioncx, borrows_out_of_scope_at_location, - borrow_index, borrow_region, target.start_location() + borrow_index, borrow_region, target.start_location(), + visited_locations ); if let Some(block) = cleanup { precompute_borrows_out_of_scope( mir, regioncx, borrows_out_of_scope_at_location, - borrow_index, borrow_region, block.start_location() + borrow_index, borrow_region, block.start_location(), + visited_locations ); } }, @@ -142,7 +157,7 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>( } else { precompute_borrows_out_of_scope(mir, regioncx, borrows_out_of_scope_at_location, borrow_index, borrow_region, - location.successor_within_block()); + location.successor_within_block(), visited_locations); } } @@ -167,7 +182,8 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { precompute_borrows_out_of_scope(mir, &nonlexical_regioncx, &mut borrows_out_of_scope_at_location, - borrow_index, borrow_region, location); + borrow_index, borrow_region, location, + &mut Vec::new()); } Borrows {