rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.5k stars 12.73k forks source link

ICE: 1.0.0 panick compiling stage1 libcore when librustc_lint/builtins.rs check_expr calls i32::MIN::abs() #25492

Closed econoplas closed 9 years ago

econoplas commented 9 years ago

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:

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
econoplas commented 9 years ago

Closing this issue as my patch incorrectly produces warnings for values like -128i8 and -32768i16 and -2147483648i32, which is clearly incorrect. I should have tested more thoroughly before posting the issue. I will keep digging for another work-around.