From 3b4d2dc17bdbbb3c927b00482ff1f9701c2ca396 Mon Sep 17 00:00:00 2001 From: c42f Date: Tue, 22 Nov 2022 17:00:53 +1000 Subject: [PATCH] Only warn when float literals underflow to zero jl_strtod_c can return "underflow" even for valid cases such as `5e-324` where the source string is parsed to an exact Float64 representation. So we can't rely on jl_strtod_c to detect "invalid" underflow. Rather, only warn when underflowing to zero which is probably a programming mistake. --- src/parse_stream.jl | 14 ++++++++++---- test/diagnostics.jl | 8 ++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/parse_stream.jl b/src/parse_stream.jl index e073d90f..01ae8ee9 100644 --- a/src/parse_stream.jl +++ b/src/parse_stream.jl @@ -865,10 +865,16 @@ function validate_literal_tokens(stream::ParseStream) # parse_int_literal # parse_uint_literal elseif k == K"Float" || k == K"Float32" + underflow0 = false if k == K"Float" - _, code = parse_float_literal(Float64, text, fbyte, nbyte) + x, code = parse_float_literal(Float64, text, fbyte, nbyte) + # jl_strtod_c can return "underflow" even for valid cases such + # as `5e-324` where the source is an exact representation of + # `x`. So only warn when underflowing to zero. + underflow0 = code == :underflow && x == 0 else - _, code = parse_float_literal(Float32, text, fbyte, nbyte) + x, code = parse_float_literal(Float32, text, fbyte, nbyte) + underflow0 = code == :underflow && x == 0 end if code == :ok # pass @@ -876,9 +882,9 @@ function validate_literal_tokens(stream::ParseStream) emit_diagnostic(stream, fbyte, lbyte, error="overflow in floating point literal") had_error = true - elseif code == :underflow + elseif underflow0 emit_diagnostic(stream, fbyte, lbyte, - warning="underflow in floating point literal") + warning="underflow to zero in floating point literal") end elseif k == K"Char" @assert fbyte < nbyte # Already handled in the parser diff --git a/test/diagnostics.jl b/test/diagnostics.jl index 9e3c8000..3324b2b0 100644 --- a/test/diagnostics.jl +++ b/test/diagnostics.jl @@ -16,9 +16,13 @@ end @test diagnostic("x = 10.0f1000;") == Diagnostic(5, 13, :error, "overflow in floating point literal") @test diagnostic("x = 10.0e-1000;") == - Diagnostic(5, 14, :warning, "underflow in floating point literal") + Diagnostic(5, 14, :warning, "underflow to zero in floating point literal") @test diagnostic("x = 10.0f-1000;") == - Diagnostic(5, 14, :warning, "underflow in floating point literal") + Diagnostic(5, 14, :warning, "underflow to zero in floating point literal") + # Underflow boundary + @test diagnostic("5e-324", allow_multiple=true) == [] + @test diagnostic("2e-324") == + Diagnostic(1, 6, :warning, "underflow to zero in floating point literal") # Char @test diagnostic("x = ''") ==