authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-08-21 02:27:11+01:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-08-21 11:47:31+03:00
log283afb50b56fb8a2c288d2452bdf6e595a1bbb06
tree074cfa8a07a8763d455289a20fc0b08e1b0395be
parent411462e1cdac518ccb67a8dd7aa5ef93332f8d19

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

5 files changed, 22 insertions(+), 18 deletions(-)

lib/std/math/big/int_test.zig-13
...@@ -2317,17 +2317,6 @@ test "big.int bitwise xor single negative simple" {...@@ -2317,17 +2317,6 @@ test "big.int bitwise xor single negative simple" {
2317 try testing.expect((try a.to(i64)) == -0x2efed94fcb932ef9);2317 try testing.expect((try a.to(i64)) == -0x2efed94fcb932ef9);
2318}2318}
23192319
2320test "big.int bitwise xor single negative zero" {
2321 var a = try Managed.initSet(testing.allocator, 0);
2322 defer a.deinit();
2323 var b = try Managed.initSet(testing.allocator, -0);
2324 defer b.deinit();
2325
2326 try a.bitXor(&a, &b);
2327
2328 try testing.expect(a.eqlZero());
2329}
2330
2331test "big.int bitwise xor single negative multi-limb" {2320test "big.int bitwise xor single negative multi-limb" {
2332 var a = try Managed.initSet(testing.allocator, -0x9849c6e7a10d66d0e4260d4846254c32);2321 var a = try Managed.initSet(testing.allocator, -0x9849c6e7a10d66d0e4260d4846254c32);
2333 defer a.deinit();2322 defer a.deinit();
...@@ -2687,8 +2676,6 @@ test "big int popcount" {...@@ -2687,8 +2676,6 @@ test "big int popcount" {
2687 try a.set(0);2676 try a.set(0);
2688 try popCountTest(&a, 0, 0);2677 try popCountTest(&a, 0, 0);
2689 try popCountTest(&a, 567, 0);2678 try popCountTest(&a, 567, 0);
2690 try a.set(-0);
2691 try popCountTest(&a, 0, 0);
26922679
2693 try a.set(1);2680 try a.set(1);
2694 try popCountTest(&a, 1, 1);2681 try popCountTest(&a, 1, 1);
lib/std/math/pow.zig+2-2
...@@ -209,8 +209,8 @@ test "math.pow.special" {...@@ -209,8 +209,8 @@ test "math.pow.special" {
209 try expect(pow(f32, -45, 1.0) == -45);209 try expect(pow(f32, -45, 1.0) == -45);
210 try expect(math.isNan(pow(f32, math.nan(f32), 5.0)));210 try expect(math.isNan(pow(f32, math.nan(f32), 5.0)));
211 try expect(math.isPositiveInf(pow(f32, -math.inf(f32), 0.5)));211 try expect(math.isPositiveInf(pow(f32, -math.inf(f32), 0.5)));
212 try expect(math.isPositiveInf(pow(f32, -0, -0.5)));212 try expect(math.isPositiveInf(pow(f32, -0.0, -0.5)));
213 try expect(pow(f32, -0, 0.5) == 0);213 try expect(pow(f32, -0.0, 0.5) == 0);
214 try expect(math.isNan(pow(f32, 5.0, math.nan(f32))));214 try expect(math.isNan(pow(f32, 5.0, math.nan(f32))));
215 try expect(math.isPositiveInf(pow(f32, 0.0, -1.0)));215 try expect(math.isPositiveInf(pow(f32, 0.0, -1.0)));
216 //expect(math.isNegativeInf(pow(f32, -0.0, -3.0))); TODO is this required?216 //expect(math.isNegativeInf(pow(f32, -0.0, -3.0))); TODO is this required?
src/AstGen.zig+9-1
...@@ -7270,7 +7270,15 @@ fn numberLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index, source_node:...@@ -7270,7 +7270,15 @@ fn numberLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index, source_node:
72707270
7271 const result: Zir.Inst.Ref = switch (std.zig.parseNumberLiteral(bytes)) {7271 const result: Zir.Inst.Ref = switch (std.zig.parseNumberLiteral(bytes)) {
7272 .int => |num| switch (num) {7272 .int => |num| switch (num) {
7273 0 => .zero,7273 0 => if (sign == .positive) .zero else return astgen.failTokNotes(
7274 num_token,
7275 "integer literal '-0' is ambiguous",
7276 .{},
7277 &.{
7278 try astgen.errNoteTok(num_token, "use '0' for an integer zero", .{}),
7279 try astgen.errNoteTok(num_token, "use '-0.0' for a floating-point signed zero", .{}),
7280 },
7281 ),
7274 1 => .one,7282 1 => .one,
7275 else => try gz.addInt(num),7283 else => try gz.addInt(num),
7276 },7284 },
test/behavior/bitcast.zig-2
...@@ -63,8 +63,6 @@ fn testBitCast(comptime N: usize) !void {...@@ -63,8 +63,6 @@ fn testBitCast(comptime N: usize) !void {
63 try expect(conv_uN(N, 0) == 0);63 try expect(conv_uN(N, 0) == 0);
64 try expect(conv_iN(N, 0) == 0);64 try expect(conv_iN(N, 0) == 0);
6565
66 try expect(conv_iN(N, -0) == 0);
67
68 if (N > 24) {66 if (N > 24) {
69 try expect(conv_uN(N, 0xf23456) == 0xf23456);67 try expect(conv_uN(N, 0xf23456) == 0xf23456);
70 }68 }
test/cases/compile_errors/negative_zero_literal.zig created+11
...@@ -0,0 +1,11 @@
1export fn foo() void {
2 _ = -0;
3}
4
5// error
6// backend=stage2
7// target=native
8//
9// :2:10: error: integer literal '-0' is ambiguous
10// :2:10: note: use '0' for an integer zero
11// :2:10: note: use '-0.0' for a floating-point signed zero