Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
econoplas opened this issue May 16, 2015 · 1 comment

Comments

@econoplas
Copy link
Contributor

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
@econoplas
Copy link
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant