Skip to content

ICE on too long float literals #31109

Closed

Description

@panicbit

Minimal example:

fn main() {
    let n = 0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333;
}
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
thread 'rustc' panicked at 'index out of bounds: the len is 40 but the index is 40', ../src/libcore/num/bignum.rs:312
stack backtrace:
   1:     0x7ff30d98bbf0 - sys::backtrace::tracing::imp::write::haa19c02b4de52f3bG0t
   2:     0x7ff30d9927d5 - panicking::log_panic::_<closure>::closure.41218
   3:     0x7ff30d99226f - panicking::log_panic::h527fe484e9de8fe1W7x
   4:     0x7ff30d95b8c3 - sys_common::unwind::begin_unwind_inner::h51f64b1a34c60827fTs
   5:     0x7ff30d95c228 - sys_common::unwind::begin_unwind_fmt::h0845853a1913f45blSs
   6:     0x7ff30d989a41 - rust_begin_unwind
   7:     0x7ff30d9da4ff - panicking::panic_fmt::h3967afc085fe8067LFK
   8:     0x7ff30d9da6e2 - panicking::panic_bounds_check::h3ef0001c29fc27faREK
   9:     0x7ff30d9e3b98 - num::bignum::_<impl>::mul_pow2::hf44130abcdb21a20Rcg
  10:     0x7ff30b2ffa36 - middle::const_eval::lit_to_const::hbf4c6ead21bd7490vdn
  11:     0x7ff30b2b1dde - middle::const_eval::eval_const_expr_partial::h88510700fb26a214pcm
  12:     0x7ff30b2f2bb1 - middle::const_eval::eval_const_expr::h20663b302f1cb1c1WPk
  13:     0x7ff30c5c1ece - hair::cx::expr::_<impl>::make_mirror::h291808654ea13ab1aFd
  14:     0x7ff30c59488b - build::into::_<impl>::eval_into::h6cb1b5bbafd636bfTob
  15:     0x7ff30c5a7a11 - build::stmt::_<impl>::stmts::_<closure>::closure.18489
  16:     0x7ff30c580531 - build::block::_<impl>::ast_block::h1282e09e7e411f8fdla
  17:     0x7ff30c57d586 - build::construct::h8a4ec3c0bcbd6db2cca
  18:     0x7ff30c5aa9de - mir_map::_<impl>::visit_fn::h01af1300e9119117Cid
  19:     0x7ff30c5a8a71 - mir_map::_<impl>::visit_item::hcc14ab58582fe303Nfd
  20:     0x7ff30c5a80a3 - mir_map::build_mir_for_crate::h293121b3ad2600dfWdd
  21:     0x7ff30de93a3f - driver::phase_3_run_analysis_passes::_<closure>::closure.25599
  22:     0x7ff30de75813 - middle::ty::context::_<impl>::create_and_enter::create_and_enter::h13716335538836217011
  23:     0x7ff30de71251 - driver::phase_3_run_analysis_passes::h5249241190295309167
  24:     0x7ff30de46559 - driver::compile_input::h58ee58653fb11a3ehca
  25:     0x7ff30de3877b - run_compiler::hd4933b7af1175e4aOwc
  26:     0x7ff30de35436 - sys_common::unwind::try::try_fn::try_fn::h5795434642313485966
  27:     0x7ff30d989888 - __rust_try
  28:     0x7ff30d98118b - sys_common::unwind::try::inner_try::h771fec597ec8f35cNPs
  29:     0x7ff30de35790 - boxed::_<impl>::call_box::call_box::h18189923456789545281
  30:     0x7ff30d990cd3 - sys::thread::_<impl>::new::thread_start::haf749b76474da6b089w
  31:     0x7ff3076474a3 - start_thread
  32:     0x7ff30d62013c - clone
  33:                0x0 - <unknown>

Activity

  1. added
    I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
    on Jan 22, 2016
  2. hanna-kruppe commented on Jan 22, 2016

    @hanna-kruppe
    Contributor

    This is a problem with dec2flt, also happens if you try to parse this number normally. I'll investigate.

  3. hanna-kruppe commented on Jan 22, 2016

    @hanna-kruppe
    Contributor

    Interestingly, one digit less or a couple digits more don't crash. I assume one of the many checks rejecting inputs that can't be handled is slightly off.

    However even if this panic is fixed dec2flt currently can't handle this float literal. It's a long standing issue (not filed AFAIK) to implement a different algorithm that can handle overly long inputs correctly, but in the meantime the const evaluator (in middle:const_eval::lit_to_const) may want to avoid unwraping the parse::<f64> result and instead not const eval the literal if parse returns an error. Glancing at the function signature (I know nothing about const eval) it seems that it's assumed all literals can be const eval'd. Someone who knows that code should chime in and say if this is necessary or can be changed. Without such a change, the program in the issue text still won't compile even when the immediate issue is fixed.

  4. pnkfelix commented on Jan 22, 2016

    @pnkfelix
    Contributor

    cc me

  5. pnkfelix commented on Jan 22, 2016

    @pnkfelix
    Contributor

    (slightly smaller way to reproduce the problem follows...)

    fn main() {
        let mut s = String::new();
        s.push_str("0.");
        for _ in 0..370 {
            s.push_str("3");
        }
        s.parse::<f64>();
    }
  6. hanna-kruppe commented on Jan 22, 2016

    @hanna-kruppe
    Contributor

    It only panics for between 370 and 375 '3's. This suggests changing the if max_digits < 375 in libcore/num/dec2flt/mod.rs to 369 or such will fix
    the issue. But I'd like to unterstand the cause first.

  7. hanna-kruppe commented on Jan 26, 2016

    @hanna-kruppe
    Contributor

    A shorter program that doesn't panic in float parsing but still causes an ICE for the reason described above:

    fn main() {
        let _: f64 = 1234567890123456789012345678901234567890e-340;
    }
  8. hanna-kruppe commented on Jan 27, 2016

    @hanna-kruppe
    Contributor

    BTW I have found the cause of the dec2flt panic and fixed it. I'll make a PR once I tested it some more and did something about the const eval unwrap().

    Speaking of which: I've been told there is no way around const eval, so just skipping the offending literals is apparently not possible. But I peeked at (non-MIR) trans and it doesn't seem to const eval literals, instead passing the source string to LLVM directly (in rustc_trans::consts::const_lit).

    So now I'm trying to modify const eval to give up when str::parse returns Err, which I think would stop all the programs posted in this issue from ICE-ing (and would give an ordinary const eval error if such a literal is used in a context where a constant expression is required). Someone step in and tell me if this is stupid.

    cc @oli-obk

  9. hanna-kruppe commented on Jan 27, 2016

    @hanna-kruppe
    Contributor

    Aw, turns out failing to const eval a literal will simply lead to a compiler error. So, since it's going to be an error, which is better?

    • Make it a normal error that doesn't crash the compiler, or
    • leave it as an ICE (with span_bug to have the semblance of an error message)

    It's not exactly unexpected or a bug in the compiler proper, but it's not really something that should generate a compiler error either.

  10. oli-obk commented on Jan 27, 2016

    @oli-obk
    Contributor

    We can easily make https://github.com/rust-lang/rust/blob/master/src/librustc/middle/const_eval.rs#L1322-L1346 return a Result. But wouldn't it make more sense to do the change during lowering from ast to hir and add F32 and F64 variants to the literal?

  11. hanna-kruppe commented on Jan 27, 2016

    @hanna-kruppe
    Contributor

    I did change lit_to_const to return Result, but that lead to a compiler error. I assume some part of the compiler tries to force const eval of literals (i.e., calls eval_const_expr_partial and errors out if that fails). Perhaps that too can be changed but at this point I'm pretty far out of my depth.

    But wouldn't it make more sense to do the change during lowering from ast to hir and add F32 and F64 variants to the literal?

    I'm not sure what this has to do with this issue, can you elaborate? This ICE happens because str::parse can't handle some valid literals that are accepted by libsyntax and the rest of the compiler.

  12. oli-obk commented on Jan 27, 2016

    @oli-obk
    Contributor

    I'm not sure what this has to do with this issue, can you elaborate? This ICE happens because str::parse can't handle some valid literals that are accepted by libsyntax and the rest of the compiler.

    I mean that we can attempt to parse and it fails, emit an error and yield a NaN instead. At some point the compiler will stop due to the emitted error. Before that, whatever tries to use the float will get a NaN. It will save all stages using the HIR from having to work with actual textual float literals.

  13. hanna-kruppe commented on Jan 27, 2016

    @hanna-kruppe
    Contributor

    That sounds like a sensible change in general, but I still don't see the relation to this issue

    1. It seems to me the same effect (in terms of error messages) could be achieved by just returning NaN from lit_to_const without any changes to HIR?
    2. Carrying on with a plainly wrong value could have all sorts of undesirable side effects (e.g. I'd have to check if it confuses the overflowing_literals lint) and I'm not sure if it has any upsides vs. just emitting a fatal error. Recall that this is a very rare edge case.
  14. oli-obk commented on Jan 27, 2016

    @oli-obk
    Contributor

    good point. So simply emitting a fatal error in lit_to_const should fix the ICE.

  15. hanna-kruppe commented on Jan 27, 2016

    @hanna-kruppe
    Contributor

    I still wonder whether a fatal error (span_fatal) or an ICE with a message (span_bug) is more appropriate. It is a bug after all, but we don't really need more reports of it and there is also precedent for having an error for a temporary limitation (cf. #31232). Leaning towards fatal error now.

  16. 11 remaining items

  17. added a commit that references this issue on Jul 17, 2021
    f502bd3
  18. added a commit that references this issue on Apr 14, 2023
  19. added 2 commits that reference this issue on Apr 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions