From e244f625bebb86dbbf5f80da3a5fbcc0eca32dd1 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 22 May 2019 15:17:38 -0700 Subject: Add test for DropAndReplace bug --- src/test/run-pass/generator/drop-and-replace.rs | 44 +++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/test/run-pass/generator/drop-and-replace.rs (limited to 'src/test') diff --git a/src/test/run-pass/generator/drop-and-replace.rs b/src/test/run-pass/generator/drop-and-replace.rs new file mode 100644 index 00000000000..042e1276db5 --- /dev/null +++ b/src/test/run-pass/generator/drop-and-replace.rs @@ -0,0 +1,44 @@ +// Regression test for incorrect DropAndReplace behavior introduced in #60840 +// and fixed in #61373. When combined with the optimization implemented in +// #60187, this produced incorrect code for generators when a saved local was +// re-assigned. + +#![feature(generators, generator_trait)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; + +#[derive(Debug, PartialEq)] +struct Foo(i32); + +impl Drop for Foo { + fn drop(&mut self) { } +} + +fn main() { + let mut a = || { + let mut x = Foo(4); + yield; + assert_eq!(x.0, 4); + + // At one point this tricked our dataflow analysis into thinking `x` was + // StorageDead after the assignment. + x = Foo(5); + assert_eq!(x.0, 5); + + { + let y = Foo(6); + yield; + assert_eq!(y.0, 6); + } + + assert_eq!(x.0, 5); + }; + + loop { + match Pin::new(&mut a).resume() { + GeneratorState::Complete(()) => break, + _ => (), + } + } +} -- cgit 1.4.1-3-g733a5 From 7718b14301b96c06c97d2c200508e0703b3de953 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 31 May 2019 18:49:22 -0700 Subject: Test StorageDead statements explicitly --- src/test/mir-opt/generator-storage-dead-unwind.rs | 106 ++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/test/mir-opt/generator-storage-dead-unwind.rs (limited to 'src/test') diff --git a/src/test/mir-opt/generator-storage-dead-unwind.rs b/src/test/mir-opt/generator-storage-dead-unwind.rs new file mode 100644 index 00000000000..7be17c4292a --- /dev/null +++ b/src/test/mir-opt/generator-storage-dead-unwind.rs @@ -0,0 +1,106 @@ +// ignore-wasm32-bare compiled with panic=abort by default + +// Test that we generate StorageDead on unwind paths for generators. +// +// Basic block and local names can safely change, but the StorageDead statements +// should not go away. + +#![feature(generators, generator_trait)] + +struct Foo(i32); + +impl Drop for Foo { + fn drop(&mut self) {} +} + +struct Bar(i32); + +fn take(_x: T) {} + +fn main() { + let _gen = || { + let a = Foo(5); + let b = Bar(6); + yield; + take(a); + take(b); + }; +} + +// END RUST SOURCE + +// START rustc.main-{{closure}}.StateTransform.before.mir +// ... +// let _2: Foo; +// ... +// let mut _7: Foo; +// ... +// let mut _9: Bar; +// scope 1 { +// let _3: Bar; +// scope 2 { +// } +// } +// bb0: { +// StorageLive(_2); +// _2 = Foo(const 5i32,); +// StorageLive(_3); +// _3 = Bar(const 6i32,); +// ... +// _1 = suspend(move _5) -> [resume: bb2, drop: bb4]; +// } +// bb1 (cleanup): { +// resume; +// } +// bb2: { +// ... +// StorageLive(_7); +// _7 = move _2; +// _6 = const take::(move _7) -> [return: bb9, unwind: bb8]; +// } +// bb3 (cleanup): { +// StorageDead(_2); +// drop(_1) -> bb1; +// } +// bb4: { +// ... +// StorageDead(_3); +// drop(_2) -> [return: bb5, unwind: bb3]; +// } +// bb5: { +// StorageDead(_2); +// drop(_1) -> [return: bb6, unwind: bb1]; +// } +// bb6: { +// generator_drop; +// } +// bb7 (cleanup): { +// StorageDead(_3); +// StorageDead(_2); +// drop(_1) -> bb1; +// } +// bb8 (cleanup): { +// StorageDead(_7); +// goto -> bb7; +// } +// bb9: { +// StorageDead(_7); +// StorageLive(_9); +// _9 = move _3; +// _8 = const take::(move _9) -> [return: bb10, unwind: bb11]; +// } +// bb10: { +// StorageDead(_9); +// ... +// StorageDead(_3); +// StorageDead(_2); +// drop(_1) -> [return: bb12, unwind: bb1]; +// } +// bb11 (cleanup): { +// StorageDead(_9); +// goto -> bb7; +// } +// bb12: { +// return; +// } +// END rustc.main-{{closure}}.StateTransform.before.mir -- cgit 1.4.1-3-g733a5