Description
I included a patch for review below rather than forking all of rust to propose a change to 3 lines of code.
Even though the subject says 1.0.0 this fix may be applicable to master and 1.1.0-dev as well.
Problem:
Building rust-1.0.0 from source crashes building stage1 libcore due to librustc_lint/builtins.rs in TypeLimits.LintPass::check_expr calling MIN::abs() resulting in panick at 'arithmetic operation overflowed'.
This is coincidentally related to the decision to close #25378 and not back-port range check to abs() since the abs() panic issue had already been fixed in master and 1.1.0-dev (confirmed).
In librustc_lint/builtins.rs check_expr can easily be modified to eliminate the need to call i32::MIN::abs() and avoid the panic during compile. The call to abs() is within a match block that deals only with signed integer literals with a positive sign (as far as I can tell that's what ast::Plus means), so there should not be a need to check for negative or call min.abs() here:
match lit.node {
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
let int_type = if let ast::TyIs = t {
cx.sess().target.int_type
} else {
t
};
let (min, max) = int_ty_range(int_type);
let negative = self.negated_expr_id == e.id;
if (negative && v > (min.abs() as u64)) ||
(!negative && v > (max.abs() as u64)) {
cx.span_lint(OVERFLOWING_LITERALS, e.span,
&*format!("literal out of range for {:?}", t));
return;
}
}
_ => panic!()
};
I am contributing the following patch against 1.0.0 but this same fix applies to master and 1.1.0-dev as far as I can tell. Not only does this fix the compile panic issue by not calling abs() and also simplifies the code a bit in this section:
--- rustc-1.0.0/src/librustc_lint/builtin.rs 2015-05-13 14:03:53.000000000 -0600
+++ rustc-1.0.0-fix/src/librustc_lint/builtin.rs 2015-05-16 05:43:01.743023679 -0600
@@ -203,11 +203,9 @@
} else {
t
};
- let (min, max) = int_ty_range(int_type);
- let negative = self.negated_expr_id == e.id;
+ let (_, max) = int_ty_range(int_type);
- if (negative && v > (min.abs() as u64)) ||
- (!negative && v > (max.abs() as u64)) {
+ if v as u64 > max as u64 {
cx.span_lint(OVERFLOWING_LITERALS, e.span,
&*format!("literal out of range for {:?}", t));
return;
I tried this code:
$ tar xpf rustc-1.0.0.tar.gz
$ mkdir objdir2 && cd objdir2
$ ../rustc-1.0.0/configure --prefix=/opt/rust-1.0.0 --enable-debug
$ make
I expected to see this happen:
A successful compile of rust 1.0.0 from sources.
Instead, this happened:
thread 'rustc' panicked at 'arithmetic operation overflowed', /tmp/build/rustc-1.0.0/src/libcore/num/mod.rs:509
NOTES:
- After applying the above patch and building from source, the compile succeeds.
- I searched for calls to abs() throughout the entire 1.0.0 code base, and read each section of code carefully and this is the only place I could find where the Rust code is unsafely calling MIN::abs() explicitly. Of course I might have missed some... so no promises :-)
Meta
Backtrace:
rustc: x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'arithmetic operation overflowed', /tmp/build/rustc-1.0.0/src/libcore/num/mod.rs:509
stack backtrace:
1: 0x7ff6d201edb9 - sys::backtrace::write::h8d09b01541635165Jbs
2: 0x7ff6d20479f6 - panicking::on_panic::h2487ac057a176b0fjzw
3: 0x7ff6d1f826d2 - rt::unwind::begin_unwind_inner::h4490b678cd56640crew
4: 0x7ff6d1f843d7 - rt::unwind::begin_unwind_fmt::h534819c1e1059190Tcw
5: 0x7ff6d2047198 - rt::unwind::rust_begin_unwind::__rust_abi
6: 0x7ff6d20470ef - rust_begin_unwind
7: 0x7ff6d20fa737 - panicking::panic_fmt::h71ffe86f0cc817fd7uy
8: 0x7ff6d20f1366 - panicking::panic::hee65e2666c94a9b6Ety
9: 0x7ff6cfda9ca4 - num::i64::abs::h76b2a79212d52bdc4Kc
10: 0x7ff6cfda6cb6 - builtin::TypeLimits.LintPass::check_expr::h36d05f391f1e99b82ea
11: 0x7ff6cf63b4ce - lint::context::Context<'a, 'tcx>.Visitor<'v>::visit_expr::h5f1defc142190529TSs
12: 0x7ff6cf63fdbe - visit::walk_expr::h2073056950665178406
13: 0x7ff6cf63b58f - lint::context::Context<'a, 'tcx>.Visitor<'v>::visit_expr::h5f1defc142190529TSs
14: 0x7ff6cf63fe05 - visit::walk_expr::h2073056950665178406
15: 0x7ff6cf63b58f - lint::context::Context<'a, 'tcx>.Visitor<'v>::visit_expr::h5f1defc142190529TSs
16: 0x7ff6cf640638 - visit::walk_expr::h2073056950665178406
17: 0x7ff6cf63b58f - lint::context::Context<'a, 'tcx>.Visitor<'v>::visit_expr::h5f1defc142190529TSs
18: 0x7ff6cf63fd3f - visit::walk_expr::h2073056950665178406
19: 0x7ff6cf63b58f - lint::context::Context<'a, 'tcx>.Visitor<'v>::visit_expr::h5f1defc142190529TSs
20: 0x7ff6cf639972 - visit::walk_item::h10517835439163771221
21: 0x7ff6cf6318f9 - lint::context::Context<'a, 'tcx>.Visitor<'v>::visit_item::closure.90661
22: 0x7ff6cf62ca86 - lint::context::Context<'a, 'tcx>::with_lint_attrs::h14689216200692056323
23: 0x7ff6cf62ba5f - lint::context::Context<'a, 'tcx>.Visitor<'v>::visit_item::hbe2ea10fe6c84cbcbPs
24: 0x7ff6cf646fd4 - visit::walk_mod::h4547572927688307335
25: 0x7ff6cf63ba6d - lint::context::Context<'a, 'tcx>.Visitor<'v>::visit_mod::h863393cd70010bc313s
26: 0x7ff6cf639ae8 - visit::walk_item::h10517835439163771221
27: 0x7ff6cf6318f9 - lint::context::Context<'a, 'tcx>.Visitor<'v>::visit_item::closure.90661
28: 0x7ff6cf62ca86 - lint::context::Context<'a, 'tcx>::with_lint_attrs::h14689216200692056323
29: 0x7ff6cf62ba5f - lint::context::Context<'a, 'tcx>.Visitor<'v>::visit_item::hbe2ea10fe6c84cbcbPs
30: 0x7ff6cf646fd4 - visit::walk_mod::h4547572927688307335
31: 0x7ff6cf63ba6d - lint::context::Context<'a, 'tcx>.Visitor<'v>::visit_mod::h863393cd70010bc313s
32: 0x7ff6cf652d2f - visit::walk_crate::h1192268878622003131
33: 0x7ff6cf652b25 - lint::context::check_crate::closure.90724
34: 0x7ff6cf651cc6 - lint::context::Context<'a, 'tcx>::with_lint_attrs::h9210831117166459963
35: 0x7ff6cf650764 - lint::context::check_crate::hcac1e0a9a8c84de30nt
36: 0x7ff6d287ff34 - driver::phase_3_run_analysis_passes::closure.20180
37: 0x7ff6d287fb81 - util::common::time::h1088785598864004467
38: 0x7ff6d269fcb3 - driver::phase_3_run_analysis_passes::h840489b0b9cba80enGa
39: 0x7ff6d2660496 - driver::compile_input::h5e6a39ee0f44bd5cQba
40: 0x7ff6d28efc5f - run_compiler::h74998d54a9052218R4b
41: 0x7ff6d28ec80c - run::closure.22427
42: 0x7ff6d28ebcf6 - monitor::closure.22405
43: 0x7ff6d28ebbc8 - boxed::F.FnBox<A>::call_box::h6142238305265441623
44: 0x7ff6d28eb491 - boxed::Box<FnBox<A, Output $u3d$$u20$R$GT$$u2b$$u20$Send$u20$$u2b$$u20$$u27$a$GT$.FnOnce$LT$A$GT$::call_once::h15039917474495805152
45: 0x7ff6d28ea94b - thread::Builder::spawn_inner::closure.22366
46: 0x7ff6d28ea870 - rt::unwind::try::try_fn::__rust_abi::h1329427484462947387
47: 0x7ff6d28ea802 - rt::unwind::try::try_fn::h1329427484462947387
48: 0x7ff6d217f508 - rust_try_inner
49: 0x7ff6d217f4f5 - rust_try
50: 0x7ff6d28e9d19 - rt::unwind::try::h11739679040777491113
51: 0x7ff6d28e99b9 - thread::Builder::spawn_inner::closure.22296
52: 0x7ff6d28eb5d5 - boxed::F.FnBox<A>::call_box::h695873828634064800
53: 0x7ff6d1ff2aa1 - boxed::Box<FnBox<A, Output $u3d$$u20$R$GT$$u2b$$u20$Send$u20$$u2b$$u20$$u27$a$GT$.FnOnce$LT$A$GT$::call_once::h9644951886153794163
54: 0x7ff6d2015e5c - sys_common::thread::start_thread::hbb617d5de4b6791fcdr
55: 0x7ff6d20441fd - sys::thread::create::thread_start::__rust_abi
56: 0x7ff6d204418d - sys::thread::create::thread_start::h1d2a38089e369954Uxv
57: 0x7ff6caa789d0 - start_thread
58: 0x7ff6d1c068fc - clone
59: 0x0 - <unknown>
make: *** [x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.core] Error 101