Skip to content

Commit e69d234

Browse files
authored
Rollup merge of rust-lang#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](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
2 parents 2d93019 + ffc6ddd commit e69d234

File tree

6 files changed

+50
-14
lines changed

6 files changed

+50
-14
lines changed

src/librustc/session/config.rs

+6
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
804804
"save all temporary output files during compilation"),
805805
rpath: bool = (false, parse_bool, [UNTRACKED],
806806
"set rpath values in libs/exes"),
807+
overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
808+
"use overflow checks for integer arithmetic"),
807809
no_prepopulate_passes: bool = (false, parse_bool, [TRACKED],
808810
"don't pre-populate the pass manager with a list of passes"),
809811
no_vectorize_loops: bool = (false, parse_bool, [TRACKED],
@@ -2348,6 +2350,10 @@ mod tests {
23482350
opts.cg.llvm_args = vec![String::from("1"), String::from("2")];
23492351
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
23502352

2353+
opts = reference.clone();
2354+
opts.cg.overflow_checks = Some(true);
2355+
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
2356+
23512357
opts = reference.clone();
23522358
opts.cg.no_prepopulate_passes = true;
23532359
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());

src/librustc/session/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,11 @@ impl Session {
372372
pub fn nonzeroing_move_hints(&self) -> bool {
373373
self.opts.debugging_opts.enable_nonzeroing_move_hints
374374
}
375+
pub fn overflow_checks(&self) -> bool {
376+
self.opts.cg.overflow_checks
377+
.or(self.opts.debugging_opts.force_overflow_checks)
378+
.unwrap_or(self.opts.debug_assertions)
379+
}
375380

376381
pub fn must_not_eliminate_frame_pointers(&self) -> bool {
377382
self.opts.debuginfo != DebugInfoLevel::NoDebugInfo ||

src/librustc_incremental/calculate_svh/svh_visitor.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
6363
hash_spans: bool,
6464
hash_bodies: bool)
6565
-> Self {
66-
let check_overflow = tcx.sess.opts.debugging_opts.force_overflow_checks
67-
.unwrap_or(tcx.sess.opts.debug_assertions);
66+
let check_overflow = tcx.sess.overflow_checks();
6867

6968
StrictVersionHashVisitor {
7069
st: st,

src/librustc_mir/hair/cx/mod.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,8 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
5959
let mut check_overflow = attrs.iter()
6060
.any(|item| item.check_name("rustc_inherit_overflow_checks"));
6161

62-
// Respect -Z force-overflow-checks=on and -C debug-assertions.
63-
check_overflow |= infcx.tcx
64-
.sess
65-
.opts
66-
.debugging_opts
67-
.force_overflow_checks
68-
.unwrap_or(infcx.tcx.sess.opts.debug_assertions);
62+
// Respect -C overflow-checks.
63+
check_overflow |= infcx.tcx.sess.overflow_checks();
6964

7065
// Constants and const fn's always need overflow checks.
7166
check_overflow |= constness == hir::Constness::Const;

src/librustc_trans/base.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1139,11 +1139,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11391139
let ty::CrateAnalysis { export_map, reachable, name, .. } = analysis;
11401140
let exported_symbols = find_exported_symbols(tcx, reachable);
11411141

1142-
let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks {
1143-
v
1144-
} else {
1145-
tcx.sess.opts.debug_assertions
1146-
};
1142+
let check_overflow = tcx.sess.overflow_checks();
11471143

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

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -C overflow-checks
12+
13+
use std::panic;
14+
15+
fn main() {
16+
let r = panic::catch_unwind(|| {
17+
[1, i32::max_value()].iter().sum::<i32>();
18+
});
19+
assert!(r.is_err());
20+
21+
let r = panic::catch_unwind(|| {
22+
[2, i32::max_value()].iter().product::<i32>();
23+
});
24+
assert!(r.is_err());
25+
26+
let r = panic::catch_unwind(|| {
27+
[1, i32::max_value()].iter().cloned().sum::<i32>();
28+
});
29+
assert!(r.is_err());
30+
31+
let r = panic::catch_unwind(|| {
32+
[2, i32::max_value()].iter().cloned().product::<i32>();
33+
});
34+
assert!(r.is_err());
35+
}

0 commit comments

Comments
 (0)