about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-07-23 03:06:08 +0000
committerbors <bors@rust-lang.org>2018-07-23 03:06:08 +0000
commit210d61f05c8c2f9e58f167eb28ab9d8bbef4968b (patch)
tree64835cc660ba2f197f64f16039724c7f28e0382e
parent02b0479c26b389f08e51da4fc5b6e99488fdb96f (diff)
parent233a6e13ca2f6dec6590a6bf92dd73de303a9d00 (diff)
Auto merge of #52571 - oli-obk:promotion_abort, r=nagisa
Abort if a promoted fails to be const evaluable and its runtime checks didn't trigger

r? @eddyb

cc @RalfJung @nagisa

cc https://github.com/rust-lang/rust/issues/49760
-rw-r--r--src/librustc_codegen_llvm/mir/operand.rs11
-rw-r--r--src/test/run-pass/invalid_const_promotion.rs38
2 files changed, 46 insertions, 3 deletions
diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs
index 5d36eef99af..52234af08c1 100644
--- a/src/librustc_codegen_llvm/mir/operand.rs
+++ b/src/librustc_codegen_llvm/mir/operand.rs
@@ -18,7 +18,7 @@ use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::sync::Lrc;
 
 use base;
-use common::{CodegenCx, C_null, C_undef, C_usize};
+use common::{CodegenCx, C_undef, C_usize};
 use builder::{Builder, MemFlags};
 use value::Value;
 use type_of::LayoutLlvmExt;
@@ -411,7 +411,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
                     .unwrap_or_else(|err| {
                         match constant.literal {
                             mir::Literal::Promoted { .. } => {
-                                // FIXME: generate a panic here
+                                // this is unreachable as long as runtime
+                                // and compile-time agree on values
+                                // With floats that won't always be true
+                                // so we generate an abort below
                             },
                             mir::Literal::Value { .. } => {
                                 err.report_as_error(
@@ -420,10 +423,12 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
                                 );
                             },
                         }
+                        let fnname = bx.cx.get_intrinsic(&("llvm.trap"));
+                        bx.call(fnname, &[], None);
                         // We've errored, so we don't have to produce working code.
                         let layout = bx.cx.layout_of(ty);
                         PlaceRef::new_sized(
-                            C_null(layout.llvm_type(bx.cx).ptr_to()),
+                            C_undef(layout.llvm_type(bx.cx).ptr_to()),
                             layout,
                             layout.align,
                         ).load(bx)
diff --git a/src/test/run-pass/invalid_const_promotion.rs b/src/test/run-pass/invalid_const_promotion.rs
new file mode 100644
index 00000000000..29a4b921992
--- /dev/null
+++ b/src/test/run-pass/invalid_const_promotion.rs
@@ -0,0 +1,38 @@
+// Copyright 2018 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.
+
+// ignore-wasm32
+// ignore-emscripten
+
+#![feature(const_fn)]
+#![allow(const_err)]
+
+use std::env;
+use std::process::{Command, Stdio};
+
+const fn bar() -> usize { 0 - 1 }
+
+fn foo() {
+    let _: &'static _ = &bar();
+}
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() > 1 && args[1] == "test" {
+        foo();
+        return;
+    }
+
+    let mut p = Command::new(&args[0])
+        .stdout(Stdio::piped())
+        .stdin(Stdio::piped())
+        .arg("test").output().unwrap();
+    assert!(!p.status.success());
+}