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" {
23172317 try testing.expect((try a.to(i64)) == -0x2efed94fcb932ef9);
23182318}
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
23312320test "big.int bitwise xor single negative multi-limb" {
23322321 var a = try Managed.initSet(testing.allocator, -0x9849c6e7a10d66d0e4260d4846254c32);
23332322 defer a.deinit();
......@@ -2687,8 +2676,6 @@ test "big int popcount" {
26872676 try a.set(0);
26882677 try popCountTest(&a, 0, 0);
26892678 try popCountTest(&a, 567, 0);
2690 try a.set(-0);
2691 try popCountTest(&a, 0, 0);
26922679
26932680 try a.set(1);
26942681 try popCountTest(&a, 1, 1);
lib/std/math/pow.zig+2-2
......@@ -209,8 +209,8 @@ test "math.pow.special" {
209209 try expect(pow(f32, -45, 1.0) == -45);
210210 try expect(math.isNan(pow(f32, math.nan(f32), 5.0)));
211211 try expect(math.isPositiveInf(pow(f32, -math.inf(f32), 0.5)));
212 try expect(math.isPositiveInf(pow(f32, -0, -0.5)));
213 try expect(pow(f32, -0, 0.5) == 0);
212 try expect(math.isPositiveInf(pow(f32, -0.0, -0.5)));
213 try expect(pow(f32, -0.0, 0.5) == 0);
214214 try expect(math.isNan(pow(f32, 5.0, math.nan(f32))));
215215 try expect(math.isPositiveInf(pow(f32, 0.0, -1.0)));
216216 //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:
72707270
72717271 const result: Zir.Inst.Ref = switch (std.zig.parseNumberLiteral(bytes)) {
72727272 .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 ),
72747282 1 => .one,
72757283 else => try gz.addInt(num),
72767284 },
test/behavior/bitcast.zig-2
......@@ -63,8 +63,6 @@ fn testBitCast(comptime N: usize) !void {
6363 try expect(conv_uN(N, 0) == 0);
6464 try expect(conv_iN(N, 0) == 0);
6565
66 try expect(conv_iN(N, -0) == 0);
67
6866 if (N > 24) {
6967 try expect(conv_uN(N, 0xf23456) == 0xf23456);
7068 }
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