@@ -273,16 +273,25 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
273273 }
274274
275275 /// Extract the mutated place from a statement.
276+ ///
277+ /// This method returns the `Place` so we can flood the state in case of a partial assignment.
278+ /// (_1 as Ok).0 = _5;
279+ /// (_1 as Err).0 = _6;
280+ /// We want to ensure that a `SwitchInt((_1 as Ok).0)` does not see the first assignment, as
281+ /// the value may have been mangled by the second assignment.
282+ ///
283+ /// In case we assign to a discriminant, we return `Some(TrackElem::Discriminant)`, so we can
284+ /// stop at flooding the discriminant, and preserve the variant fields.
285+ /// (_1 as Some).0 = _6;
286+ /// SetDiscriminant(_1, 1);
287+ /// switchInt((_1 as Some).0)
276288 #[ instrument( level = "trace" , skip( self ) , ret) ]
277289 fn mutated_statement (
278290 & self ,
279291 stmt : & Statement < ' tcx > ,
280292 ) -> Option < ( Place < ' tcx > , Option < TrackElem > ) > {
281293 match stmt. kind {
282294 StatementKind :: Assign ( box ( place, _) )
283- | StatementKind :: Intrinsic ( box NonDivergingIntrinsic :: Assume (
284- Operand :: Copy ( place) | Operand :: Move ( place) ,
285- ) )
286295 | StatementKind :: Deinit ( box place) => Some ( ( place, None ) ) ,
287296 StatementKind :: SetDiscriminant { box place, variant_index : _ } => {
288297 Some ( ( place, Some ( TrackElem :: Discriminant ) ) )
@@ -291,7 +300,9 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
291300 Some ( ( Place :: from ( local) , None ) )
292301 }
293302 StatementKind :: Retag ( ..)
294- | StatementKind :: Intrinsic ( ..)
303+ | StatementKind :: Intrinsic ( box NonDivergingIntrinsic :: Assume ( ..) )
304+ // copy_nonoverlapping takes pointers and mutated the pointed-to value.
305+ | StatementKind :: Intrinsic ( box NonDivergingIntrinsic :: CopyNonOverlapping ( ..) )
295306 | StatementKind :: AscribeUserType ( ..)
296307 | StatementKind :: Coverage ( ..)
297308 | StatementKind :: FakeRead ( ..)
0 commit comments