Skip to content

Commit

Permalink
Auto merge of #52571 - oli-obk:promotion_abort, r=nagisa
Browse files Browse the repository at this point in the history
Abort if a promoted fails to be const evaluable and its runtime checks didn't trigger

r? @eddyb

cc @RalfJung @nagisa

cc #49760
  • Loading branch information
bors committed Jul 23, 2018
2 parents 02b0479 + 233a6e1 commit 210d61f
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/librustc_codegen_llvm/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand All @@ -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)
Expand Down
38 changes: 38 additions & 0 deletions src/test/run-pass/invalid_const_promotion.rs
Original file line number Diff line number Diff line change
@@ -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());
}

0 comments on commit 210d61f

Please sign in to comment.