Rollup merge of #40037 - froydnj:overflow-checks, r=alexcrichton
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](b1363a73ed/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 #33134. r? @alexcrichton
This commit is contained in:
commit
582d5d9793
@ -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],
|
||||
@ -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());
|
||||
|
@ -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 ||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
35
src/test/run-pass/iter-sum-overflow-overflow-checks.rs
Normal file
35
src/test/run-pass/iter-sum-overflow-overflow-checks.rs
Normal file
@ -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());
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user