summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <andersrb@gmail.com>2016-09-16 00:46:50 +0000
committerGitHub <noreply@github.com>2016-09-16 00:46:50 +0000
commit0f7ea2ad39bb87966ccdedfd071ee350ecad54d1 (patch)
tree517c2b3d6474412c8503e14aa2fd3eadd5eec089
parent389dad798e99ba4333066ffcafed7ed2aa5a89d9 (diff)
parent74cf38c9e8e08c7e7e3e6f61c45131b13fc5b001 (diff)
downloadrust-0f7ea2ad39bb87966ccdedfd071ee350ecad54d1.tar.gz
rust-0f7ea2ad39bb87966ccdedfd071ee350ecad54d1.zip
Merge pull request #36433 from alexcrichton/beta-next
Backport PRs to beta
-rw-r--r--src/librustc/middle/liveness.rs8
-rw-r--r--src/librustc_trans/mir/analyze.rs6
-rw-r--r--src/librustc_typeck/check/mod.rs8
-rw-r--r--src/libstd/memchr.rs24
m---------src/llvm0
-rw-r--r--src/rustllvm/llvm-auto-clean-trigger2
-rw-r--r--src/test/compile-fail/diverging-fn-tail-35849.rs16
-rw-r--r--src/test/run-fail/call-fn-never-arg.rs1
-rw-r--r--src/test/run-pass/diverging-fn-tail-35849.rs18
-rw-r--r--src/test/run-pass/issue-36023.rs32
-rw-r--r--src/test/run-pass/mir_heavy_promoted.rs18
11 files changed, 129 insertions, 4 deletions
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 74d29b273ff..b83826de26d 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -1479,7 +1479,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 self.ir.tcx.region_maps.call_site_extent(id, body.id),
                 &self.fn_ret(id));
 
-        if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() {
+        if fn_ret.is_never() {
+            // FIXME(durka) this rejects code like `fn foo(x: !) -> ! { x }`
+            if self.live_on_entry(entry_ln, self.s.clean_exit_var).is_some() {
+                span_err!(self.ir.tcx.sess, sp, E0270,
+                          "computation may converge in a function marked as diverging");
+            }
+        } else if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() {
             let param_env = ParameterEnvironment::for_item(self.ir.tcx, id);
             let t_ret_subst = fn_ret.subst(self.ir.tcx, &param_env.free_substs);
             let is_nil = self.ir.tcx.infer_ctxt(None, Some(param_env),
diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs
index e0d959f4774..66eb78aef07 100644
--- a/src/librustc_trans/mir/analyze.rs
+++ b/src/librustc_trans/mir/analyze.rs
@@ -48,6 +48,12 @@ pub fn lvalue_locals<'bcx, 'tcx>(bcx: Block<'bcx,'tcx>,
                     common::type_is_fat_ptr(bcx.tcx(), ty));
         } else if common::type_is_imm_pair(bcx.ccx(), ty) {
             // We allow pairs and uses of any of their 2 fields.
+        } else if !analyzer.seen_assigned.contains(index) {
+            // No assignment has been seen, which means that
+            // either the local has been marked as lvalue
+            // already, or there is no possible initialization
+            // for the local, making any reads invalid.
+            // This is useful in weeding out dead temps.
         } else {
             // These sorts of types require an alloca. Note that
             // type_is_immediate() may *still* be true, particularly
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index d985d3ccbea..5dae28c12a0 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -709,7 +709,13 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
 
     inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig);
 
-    fcx.check_block_with_expected(body, ExpectHasType(fcx.ret_ty));
+    // FIXME(aburka) do we need this special case? and should it be is_uninhabited?
+    let expected = if fcx.ret_ty.is_never() {
+        NoExpectation
+    } else {
+        ExpectHasType(fcx.ret_ty)
+    };
+    fcx.check_block_with_expected(body, expected);
 
     fcx
 }
diff --git a/src/libstd/memchr.rs b/src/libstd/memchr.rs
index a408b4378e1..03f55f7ad61 100644
--- a/src/libstd/memchr.rs
+++ b/src/libstd/memchr.rs
@@ -209,7 +209,7 @@ mod fallback {
         let end_align = (ptr as usize + len) & (usize_bytes - 1);
         let mut offset;
         if end_align > 0 {
-            offset = len - cmp::min(usize_bytes - end_align, len);
+            offset = if end_align >= len { 0 } else { len - end_align };
             if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
                 return Some(offset + index);
             }
@@ -309,6 +309,17 @@ mod fallback {
     fn no_match_reversed() {
         assert_eq!(None, memrchr(b'a', b"xyz"));
     }
+
+    #[test]
+    fn each_alignment_reversed() {
+        let mut data = [1u8; 64];
+        let needle = 2;
+        let pos = 40;
+        data[pos] = needle;
+        for start in 0..16 {
+            assert_eq!(Some(pos - start), memrchr(needle, &data[start..]));
+        }
+    }
 }
 
 #[cfg(test)]
@@ -385,4 +396,15 @@ mod tests {
     fn no_match_reversed() {
         assert_eq!(None, memrchr(b'a', b"xyz"));
     }
+
+    #[test]
+    fn each_alignment() {
+        let mut data = [1u8; 64];
+        let needle = 2;
+        let pos = 40;
+        data[pos] = needle;
+        for start in 0..16 {
+            assert_eq!(Some(pos - start), memchr(needle, &data[start..]));
+        }
+    }
 }
diff --git a/src/llvm b/src/llvm
-Subproject 786aad117be48547f4ca50fae84c4879fa992d4
+Subproject eee68eafa7e8e4ce996b49f5551636639a6c331
diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger
index 378810a8b89..67f8730c258 100644
--- a/src/rustllvm/llvm-auto-clean-trigger
+++ b/src/rustllvm/llvm-auto-clean-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2016-08-07
+2016-08-23
diff --git a/src/test/compile-fail/diverging-fn-tail-35849.rs b/src/test/compile-fail/diverging-fn-tail-35849.rs
new file mode 100644
index 00000000000..6dc447b4dc8
--- /dev/null
+++ b/src/test/compile-fail/diverging-fn-tail-35849.rs
@@ -0,0 +1,16 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn _converge() -> ! { //~ ERROR computation may converge
+    42
+}
+
+fn main() { }
+
diff --git a/src/test/run-fail/call-fn-never-arg.rs b/src/test/run-fail/call-fn-never-arg.rs
index 95101e70db9..b1aa76cd9bf 100644
--- a/src/test/run-fail/call-fn-never-arg.rs
+++ b/src/test/run-fail/call-fn-never-arg.rs
@@ -10,6 +10,7 @@
 
 // Test that we can use a ! for an argument of type !
 
+// ignore-test FIXME(durka) can't be done with the current liveness code
 // error-pattern:wowzers!
 
 #![feature(never_type)]
diff --git a/src/test/run-pass/diverging-fn-tail-35849.rs b/src/test/run-pass/diverging-fn-tail-35849.rs
new file mode 100644
index 00000000000..6c05a02e718
--- /dev/null
+++ b/src/test/run-pass/diverging-fn-tail-35849.rs
@@ -0,0 +1,18 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn assert_sizeof() -> ! {
+    unsafe {
+        ::std::mem::transmute::<f64, [u8; 8]>(panic!())
+    }
+}
+
+fn main() { }
+
diff --git a/src/test/run-pass/issue-36023.rs b/src/test/run-pass/issue-36023.rs
new file mode 100644
index 00000000000..f6c03b384f2
--- /dev/null
+++ b/src/test/run-pass/issue-36023.rs
@@ -0,0 +1,32 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::ops::Deref;
+
+fn main() {
+    if env_var("FOOBAR").as_ref().map(Deref::deref).ok() == Some("yes") {
+        panic!()
+    }
+
+    let env_home: Result<String, ()> = Ok("foo-bar-baz".to_string());
+    let env_home = env_home.as_ref().map(Deref::deref).ok();
+
+    if env_home == Some("") { panic!() }
+}
+
+#[inline(never)]
+fn env_var(s: &str) -> Result<String, VarError> {
+    Err(VarError::NotPresent)
+}
+
+pub enum VarError {
+    NotPresent,
+    NotUnicode(String),
+}
diff --git a/src/test/run-pass/mir_heavy_promoted.rs b/src/test/run-pass/mir_heavy_promoted.rs
new file mode 100644
index 00000000000..9e033421574
--- /dev/null
+++ b/src/test/run-pass/mir_heavy_promoted.rs
@@ -0,0 +1,18 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const TEST_DATA: [u8; 32 * 1024 * 1024] = [42; 32 * 1024 * 1024];
+
+// Check that the promoted copy of TEST_DATA doesn't
+// leave an alloca from an unused temp behind, which,
+// without optimizations, can still blow the stack.
+fn main() {
+    println!("{}", TEST_DATA.len());
+}