zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 283afb50b56fb8a2c288d2452bdf6e595a1bbb06 (tree)
parent 411462e1cdac518ccb67a8dd7aa5ef93332f8d19
Author: mlugg <mlugg@mlugg.co.uk>
Date:   Mon, 21 Aug 2023 02:27:11 +0100

AstGen: disallow '-0' integer literal

The intent here is ambiguous: this resolves to the comptime_int '0', but
it's likely the user meant to use a floating-point literal.

Resolves: #16890

Diffstat:
Mlib/std/math/big/int_test.zig | 13-------------
Mlib/std/math/pow.zig | 4++--
Msrc/AstGen.zig | 10+++++++++-
Mtest/behavior/bitcast.zig | 2--
Atest/cases/compile_errors/negative_zero_literal.zig | 11+++++++++++
5 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig @@ -2317,17 +2317,6 @@ test "big.int bitwise xor single negative simple" { try testing.expect((try a.to(i64)) == -0x2efed94fcb932ef9); } -test "big.int bitwise xor single negative zero" { - var a = try Managed.initSet(testing.allocator, 0); - defer a.deinit(); - var b = try Managed.initSet(testing.allocator, -0); - defer b.deinit(); - - try a.bitXor(&a, &b); - - try testing.expect(a.eqlZero()); -} - test "big.int bitwise xor single negative multi-limb" { var a = try Managed.initSet(testing.allocator, -0x9849c6e7a10d66d0e4260d4846254c32); defer a.deinit(); @@ -2687,8 +2676,6 @@ test "big int popcount" { try a.set(0); try popCountTest(&a, 0, 0); try popCountTest(&a, 567, 0); - try a.set(-0); - try popCountTest(&a, 0, 0); try a.set(1); try popCountTest(&a, 1, 1); diff --git a/lib/std/math/pow.zig b/lib/std/math/pow.zig @@ -209,8 +209,8 @@ test "math.pow.special" { try expect(pow(f32, -45, 1.0) == -45); try expect(math.isNan(pow(f32, math.nan(f32), 5.0))); try expect(math.isPositiveInf(pow(f32, -math.inf(f32), 0.5))); - try expect(math.isPositiveInf(pow(f32, -0, -0.5))); - try expect(pow(f32, -0, 0.5) == 0); + try expect(math.isPositiveInf(pow(f32, -0.0, -0.5))); + try expect(pow(f32, -0.0, 0.5) == 0); try expect(math.isNan(pow(f32, 5.0, math.nan(f32)))); try expect(math.isPositiveInf(pow(f32, 0.0, -1.0))); //expect(math.isNegativeInf(pow(f32, -0.0, -3.0))); TODO is this required? diff --git a/src/AstGen.zig b/src/AstGen.zig @@ -7270,7 +7270,15 @@ fn numberLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index, source_node: const result: Zir.Inst.Ref = switch (std.zig.parseNumberLiteral(bytes)) { .int => |num| switch (num) { - 0 => .zero, + 0 => if (sign == .positive) .zero else return astgen.failTokNotes( + num_token, + "integer literal '-0' is ambiguous", + .{}, + &.{ + try astgen.errNoteTok(num_token, "use '0' for an integer zero", .{}), + try astgen.errNoteTok(num_token, "use '-0.0' for a floating-point signed zero", .{}), + }, + ), 1 => .one, else => try gz.addInt(num), }, diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig @@ -63,8 +63,6 @@ fn testBitCast(comptime N: usize) !void { try expect(conv_uN(N, 0) == 0); try expect(conv_iN(N, 0) == 0); - try expect(conv_iN(N, -0) == 0); - if (N > 24) { try expect(conv_uN(N, 0xf23456) == 0xf23456); } diff --git a/test/cases/compile_errors/negative_zero_literal.zig b/test/cases/compile_errors/negative_zero_literal.zig @@ -0,0 +1,11 @@ +export fn foo() void { + _ = -0; +} + +// error +// backend=stage2 +// target=native +// +// :2:10: error: integer literal '-0' is ambiguous +// :2:10: note: use '0' for an integer zero +// :2:10: note: use '-0.0' for a floating-point signed zero