| author | |
| committer | |
| log | 38b47d8aca57efbb10b8000cb726eb24b1f37ccb |
| tree | f1285716b6bce9a6ba538808c4825fb86a8e6024 |
| parent | d8227c79a2ff7882a52bf53f9ded2db4e7081fc8 |
| parent | 0705b711f8dd447f4eb4f1517be985ce09bce22f |
Correct floating-point literal allowed ranges4 files changed, 22 insertions(+), 2 deletions(-)
src/ir.cpp+1-1| ... | @@ -3704,7 +3704,7 @@ static IrInstruction *ir_gen_float_lit(IrBuilder *irb, Scope *scope, AstNode *no | ... | @@ -3704,7 +3704,7 @@ static IrInstruction *ir_gen_float_lit(IrBuilder *irb, Scope *scope, AstNode *no |
| 3704 | assert(node->type == NodeTypeFloatLiteral); | 3704 | assert(node->type == NodeTypeFloatLiteral); |
| 3705 | 3705 | ||
| 3706 | if (node->data.float_literal.overflow) { | 3706 | if (node->data.float_literal.overflow) { |
| 3707 | add_node_error(irb->codegen, node, buf_sprintf("float literal too large to be represented in any type")); | 3707 | add_node_error(irb->codegen, node, buf_sprintf("float literal out of range of any type")); |
| 3708 | return irb->codegen->invalid_instruction; | 3708 | return irb->codegen->invalid_instruction; |
| 3709 | } | 3709 | } |
| 3710 | 3710 |
src/tokenizer.cpp+1-1| ... | @@ -333,7 +333,7 @@ static void end_float_token(Tokenize *t) { | ... | @@ -333,7 +333,7 @@ static void end_float_token(Tokenize *t) { |
| 333 | } else { | 333 | } else { |
| 334 | int significand_magnitude_in_bin = __builtin_clzll(1) - __builtin_clzll(significand); | 334 | int significand_magnitude_in_bin = __builtin_clzll(1) - __builtin_clzll(significand); |
| 335 | t->exponent_in_bin_or_dec += significand_magnitude_in_bin; | 335 | t->exponent_in_bin_or_dec += significand_magnitude_in_bin; |
| 336 | if (!(-1023 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec < 1023)) { | 336 | if (!(-1022 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 1023)) { |
| 337 | t->cur_tok->data.float_lit.overflow = true; | 337 | t->cur_tok->data.float_lit.overflow = true; |
| 338 | return; | 338 | return; |
| 339 | } else { | 339 | } else { |
test/cases/math.zig+6| ... | @@ -251,3 +251,9 @@ test "allow signed integer division/remainder when values are comptime known and | ... | @@ -251,3 +251,9 @@ test "allow signed integer division/remainder when values are comptime known and |
| 251 | test "float literal parsing" { | 251 | test "float literal parsing" { |
| 252 | comptime assert(0x1.0 == 1.0); | 252 | comptime assert(0x1.0 == 1.0); |
| 253 | } | 253 | } |
| 254 | |||
| 255 | test "hex float literal within range" { | ||
| 256 | const a = 0x1.0p1023; | ||
| 257 | const b = 0x0.1p1027; | ||
| 258 | const c = 0x1.0p-1022; | ||
| 259 | } |
test/compile_errors.zig+14| ... | @@ -1931,4 +1931,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) { | ... | @@ -1931,4 +1931,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1931 | \\} | 1931 | \\} |
| 1932 | , | 1932 | , |
| 1933 | ".tmp_source.zig:1:13: error: struct 'Foo' contains itself"); | 1933 | ".tmp_source.zig:1:13: error: struct 'Foo' contains itself"); |
| 1934 | |||
| 1935 | cases.add("float literal too large error", | ||
| 1936 | \\comptime { | ||
| 1937 | \\ const a = 0x1.0p1024; | ||
| 1938 | \\} | ||
| 1939 | , | ||
| 1940 | ".tmp_source.zig:2:15: error: float literal out of range of any type"); | ||
| 1941 | |||
| 1942 | cases.add("float literal too small error (denormal)", | ||
| 1943 | \\comptime { | ||
| 1944 | \\ const a = 0x1.0p-1023; | ||
| 1945 | \\} | ||
| 1946 | , | ||
| 1947 | ".tmp_source.zig:2:15: error: float literal out of range of any type"); | ||
| 1934 | } | 1948 | } |