summaryrefslogtreecommitdiff
path: root/samples/test/gcc5_codegen_bug.rs
diff options
context:
space:
mode:
Diffstat (limited to 'samples/test/gcc5_codegen_bug.rs')
-rw-r--r--samples/test/gcc5_codegen_bug.rs38
1 files changed, 25 insertions, 13 deletions
diff --git a/samples/test/gcc5_codegen_bug.rs b/samples/test/gcc5_codegen_bug.rs
index fde709b6..60a54ea9 100644
--- a/samples/test/gcc5_codegen_bug.rs
+++ b/samples/test/gcc5_codegen_bug.rs
@@ -1,24 +1,36 @@
// compile-flags: -O
+extern crate test;
// A reduction of issue #63, where gcc5 (but not 6) will generate invalid code for the following iterator adapter's
// `next` function (seen in librustc)
// ::"core"::iter::Map<::"core"::iter::Chain<::"core"::iter::sources::Once<::"syntax"::ast::NodeId/*S*/,>/*S*/,::"core"::iter::Map<::"core"::slice::Iter<::"syntax"::codemap::Spanned<::"syntax"::ast::PathListItem_/*S*/,>/*S*/,>/*S*/,::"rustc"::closure_I_82<::"rustc"::hir::lowering::LoweringContext/*S*/,>/*S*/,>/*S*/,>/*S*/,::"rustc"::closure_I_83<::"rustc"::hir::lowering::LoweringContext/*S*/,>/*S*/,>
//
-//
-
-fn main()
-{
- // The function call is kinda needed to trigger the bug
- // - Probably because of how it sets up `rbx` to be non-zero
- println!("{:?}", foo(0, &[]));
-}
+// Symptom is an abort due to bad enum tag on Option<u32> when handling the second call to `it.next()`
-// Has to have the second map - even if it's just identity
-fn foo(n: u32, list: &[u32]) -> Vec<u32> {
- Iterator::chain(
+fn main() {
+ let n = 0;
+ let list: &[u32] = &[1]; // List can be zero length, it's appears to be the _last_ result that leads to a bad tag.
+ // Has to have the second map - even if it's just identity, first map probably needs to exist
+ let mut it = Iterator::chain(
::std::iter::once(0u32),
list.iter().map(|v| *v)
- ).map(|id| id)
- .collect()
+ ).map(|id| id);
+
+ // First works, and Foo is printed
+ it.next();
+ println!("Foo");
+ // Second one will crash with an abort (used in condition to avoid it being optimised out)
+ if it.next().is_none() {
+ println!("Bar");
+ }
+ else {
+ println!("Not-Bar");
+ }
+ if it.next().is_none() {
+ println!("Bar");
+ }
+ else {
+ println!("Not-Bar");
+ }
}