Skip to content

Commit

Permalink
Rollup merge of rust-lang#40037 - froydnj:overflow-checks, r=alexcric…
Browse files Browse the repository at this point in the history
…hton

add `-C overflow-checks` option

In addition to defining and handling the new option, we also add a method on librustc::Session for determining the necessity of overflow checks.  This method provides a single point to sort out the three (!) different ways for turning on overflow checks: -C debug-assertions, -C overflow-checks, and -Z force-overflow-checks.

I was seeing a [run-pass/issue-28950.rs](https://github.com/rust-lang/rust/blob/b1363a73ede57ae595f3a1be2bb75d308ba4f7f6/src/test/run-pass/issue-28950.rs) failure on my machine with these patches, but I was also seeing the failure without the changes to the core compiler.  We'll see what travis says.

Fixes rust-lang#33134.  r? @alexcrichton
  • Loading branch information
eddyb authored Feb 25, 2017
2 parents 2d93019 + ffc6ddd commit e69d234
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 14 deletions.
6 changes: 6 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
"save all temporary output files during compilation"),
rpath: bool = (false, parse_bool, [UNTRACKED],
"set rpath values in libs/exes"),
overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
"use overflow checks for integer arithmetic"),
no_prepopulate_passes: bool = (false, parse_bool, [TRACKED],
"don't pre-populate the pass manager with a list of passes"),
no_vectorize_loops: bool = (false, parse_bool, [TRACKED],
Expand Down Expand Up @@ -2348,6 +2350,10 @@ mod tests {
opts.cg.llvm_args = vec![String::from("1"), String::from("2")];
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());

opts = reference.clone();
opts.cg.overflow_checks = Some(true);
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());

opts = reference.clone();
opts.cg.no_prepopulate_passes = true;
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,11 @@ impl Session {
pub fn nonzeroing_move_hints(&self) -> bool {
self.opts.debugging_opts.enable_nonzeroing_move_hints
}
pub fn overflow_checks(&self) -> bool {
self.opts.cg.overflow_checks
.or(self.opts.debugging_opts.force_overflow_checks)
.unwrap_or(self.opts.debug_assertions)
}

pub fn must_not_eliminate_frame_pointers(&self) -> bool {
self.opts.debuginfo != DebugInfoLevel::NoDebugInfo ||
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_incremental/calculate_svh/svh_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
hash_spans: bool,
hash_bodies: bool)
-> Self {
let check_overflow = tcx.sess.opts.debugging_opts.force_overflow_checks
.unwrap_or(tcx.sess.opts.debug_assertions);
let check_overflow = tcx.sess.overflow_checks();

StrictVersionHashVisitor {
st: st,
Expand Down
9 changes: 2 additions & 7 deletions src/librustc_mir/hair/cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,8 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
let mut check_overflow = attrs.iter()
.any(|item| item.check_name("rustc_inherit_overflow_checks"));

// Respect -Z force-overflow-checks=on and -C debug-assertions.
check_overflow |= infcx.tcx
.sess
.opts
.debugging_opts
.force_overflow_checks
.unwrap_or(infcx.tcx.sess.opts.debug_assertions);
// Respect -C overflow-checks.
check_overflow |= infcx.tcx.sess.overflow_checks();

// Constants and const fn's always need overflow checks.
check_overflow |= constness == hir::Constness::Const;
Expand Down
6 changes: 1 addition & 5 deletions src/librustc_trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1139,11 +1139,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let ty::CrateAnalysis { export_map, reachable, name, .. } = analysis;
let exported_symbols = find_exported_symbols(tcx, reachable);

let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks {
v
} else {
tcx.sess.opts.debug_assertions
};
let check_overflow = tcx.sess.overflow_checks();

let link_meta = link::build_link_meta(incremental_hashes_map, &name);

Expand Down
35 changes: 35 additions & 0 deletions src/test/run-pass/iter-sum-overflow-overflow-checks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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.

// compile-flags: -C overflow-checks

use std::panic;

fn main() {
let r = panic::catch_unwind(|| {
[1, i32::max_value()].iter().sum::<i32>();
});
assert!(r.is_err());

let r = panic::catch_unwind(|| {
[2, i32::max_value()].iter().product::<i32>();
});
assert!(r.is_err());

let r = panic::catch_unwind(|| {
[1, i32::max_value()].iter().cloned().sum::<i32>();
});
assert!(r.is_err());

let r = panic::catch_unwind(|| {
[2, i32::max_value()].iter().cloned().product::<i32>();
});
assert!(r.is_err());
}

0 comments on commit e69d234

Please sign in to comment.