authorgravatar for r00ster91@proton.meWooster <r00ster91@proton.me> 2023-03-05 15:45:23+01:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-03-05 23:01:17+02:00
logf1ae688d371f49fdbf65f952d655905c74871fdb
treeb1855222065aa9e9b9dee3db4e7bc5240fd327f3
parent29c56a8aa74d1b1a19bece5ba5d738af1e3c9f6d

AstGen: ensure certain builtin functions return void

Fixes #14779 Co-authored-by: Veikka Tuominen <git@vexu.eu>

2 files changed, 48 insertions(+), 16 deletions(-)

src/AstGen.zig+16-16
...@@ -8060,35 +8060,35 @@ fn builtinCall(...@@ -8060,35 +8060,35 @@ fn builtinCall(
8060 },8060 },
8061 .fence => {8061 .fence => {
8062 const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[0]);8062 const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[0]);
8063 const result = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{8063 _ = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{
8064 .node = gz.nodeIndexToRelative(node),8064 .node = gz.nodeIndexToRelative(node),
8065 .operand = order,8065 .operand = order,
8066 });8066 });
8067 return rvalue(gz, ri, result, node);8067 return rvalue(gz, ri, .void_value, node);
8068 },8068 },
8069 .set_float_mode => {8069 .set_float_mode => {
8070 const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .float_mode_type } }, params[0]);8070 const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .float_mode_type } }, params[0]);
8071 const result = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{8071 _ = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{
8072 .node = gz.nodeIndexToRelative(node),8072 .node = gz.nodeIndexToRelative(node),
8073 .operand = order,8073 .operand = order,
8074 });8074 });
8075 return rvalue(gz, ri, result, node);8075 return rvalue(gz, ri, .void_value, node);
8076 },8076 },
8077 .set_align_stack => {8077 .set_align_stack => {
8078 const order = try expr(gz, scope, align_ri, params[0]);8078 const order = try expr(gz, scope, align_ri, params[0]);
8079 const result = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{8079 _ = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{
8080 .node = gz.nodeIndexToRelative(node),8080 .node = gz.nodeIndexToRelative(node),
8081 .operand = order,8081 .operand = order,
8082 });8082 });
8083 return rvalue(gz, ri, result, node);8083 return rvalue(gz, ri, .void_value, node);
8084 },8084 },
8085 .set_cold => {8085 .set_cold => {
8086 const order = try expr(gz, scope, ri, params[0]);8086 const order = try expr(gz, scope, ri, params[0]);
8087 const result = try gz.addExtendedPayload(.set_cold, Zir.Inst.UnNode{8087 _ = try gz.addExtendedPayload(.set_cold, Zir.Inst.UnNode{
8088 .node = gz.nodeIndexToRelative(node),8088 .node = gz.nodeIndexToRelative(node),
8089 .operand = order,8089 .operand = order,
8090 });8090 });
8091 return rvalue(gz, ri, result, node);8091 return rvalue(gz, ri, .void_value, node);
8092 },8092 },
80938093
8094 .src => {8094 .src => {
...@@ -8373,14 +8373,14 @@ fn builtinCall(...@@ -8373,14 +8373,14 @@ fn builtinCall(
8373 },8373 },
8374 .atomic_store => {8374 .atomic_store => {
8375 const int_type = try typeExpr(gz, scope, params[0]);8375 const int_type = try typeExpr(gz, scope, params[0]);
8376 const result = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{8376 _ = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{
8377 // zig fmt: off8377 // zig fmt: off
8378 .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]),8378 .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]),
8379 .operand = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]),8379 .operand = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]),
8380 .ordering = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[3]),8380 .ordering = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[3]),
8381 // zig fmt: on8381 // zig fmt: on
8382 });8382 });
8383 return rvalue(gz, ri, result, node);8383 return rvalue(gz, ri, .void_value, node);
8384 },8384 },
8385 .mul_add => {8385 .mul_add => {
8386 const float_type = try typeExpr(gz, scope, params[0]);8386 const float_type = try typeExpr(gz, scope, params[0]);
...@@ -8421,20 +8421,20 @@ fn builtinCall(...@@ -8421,20 +8421,20 @@ fn builtinCall(
8421 return rvalue(gz, ri, result, node);8421 return rvalue(gz, ri, result, node);
8422 },8422 },
8423 .memcpy => {8423 .memcpy => {
8424 const result = try gz.addPlNode(.memcpy, node, Zir.Inst.Memcpy{8424 _ = try gz.addPlNode(.memcpy, node, Zir.Inst.Memcpy{
8425 .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]),8425 .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]),
8426 .source = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_const_u8_type } }, params[1]),8426 .source = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_const_u8_type } }, params[1]),
8427 .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]),8427 .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]),
8428 });8428 });
8429 return rvalue(gz, ri, result, node);8429 return rvalue(gz, ri, .void_value, node);
8430 },8430 },
8431 .memset => {8431 .memset => {
8432 const result = try gz.addPlNode(.memset, node, Zir.Inst.Memset{8432 _ = try gz.addPlNode(.memset, node, Zir.Inst.Memset{
8433 .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]),8433 .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]),
8434 .byte = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u8_type } }, params[1]),8434 .byte = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u8_type } }, params[1]),
8435 .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]),8435 .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]),
8436 });8436 });
8437 return rvalue(gz, ri, result, node);8437 return rvalue(gz, ri, .void_value, node);
8438 },8438 },
8439 .shuffle => {8439 .shuffle => {
8440 const result = try gz.addPlNode(.shuffle, node, Zir.Inst.Shuffle{8440 const result = try gz.addPlNode(.shuffle, node, Zir.Inst.Shuffle{
...@@ -8475,12 +8475,12 @@ fn builtinCall(...@@ -8475,12 +8475,12 @@ fn builtinCall(
8475 .prefetch => {8475 .prefetch => {
8476 const ptr = try expr(gz, scope, .{ .rl = .none }, params[0]);8476 const ptr = try expr(gz, scope, .{ .rl = .none }, params[0]);
8477 const options = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .prefetch_options_type } }, params[1]);8477 const options = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .prefetch_options_type } }, params[1]);
8478 const result = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{8478 _ = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{
8479 .node = gz.nodeIndexToRelative(node),8479 .node = gz.nodeIndexToRelative(node),
8480 .lhs = ptr,8480 .lhs = ptr,
8481 .rhs = options,8481 .rhs = options,
8482 });8482 });
8483 return rvalue(gz, ri, result, node);8483 return rvalue(gz, ri, .void_value, node);
8484 },8484 },
8485 .c_va_arg => {8485 .c_va_arg => {
8486 if (astgen.fn_block == null) {8486 if (astgen.fn_block == null) {
test/behavior/builtin_functions_returning_void_or_noreturn.zig created+32
...@@ -0,0 +1,32 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const testing = std.testing;
4
5var x: u8 = 1;
6
7// This excludes builtin functions that return void or noreturn that cannot be tested.
8test {
9 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
16
17 var val: u8 = undefined;
18 try testing.expectEqual({}, @atomicStore(u8, &val, 0, .Unordered));
19 try testing.expectEqual(void, @TypeOf(@breakpoint()));
20 try testing.expectEqual({}, @export(x, .{ .name = "x" }));
21 try testing.expectEqual({}, @fence(.Acquire));
22 try testing.expectEqual({}, @memcpy(@intToPtr([*]u8, 1), @intToPtr([*]u8, 1), 0));
23 try testing.expectEqual({}, @memset(@intToPtr([*]u8, 1), undefined, 0));
24 try testing.expectEqual(noreturn, @TypeOf(if (true) @panic("") else {}));
25 try testing.expectEqual({}, @prefetch(&val, .{}));
26 try testing.expectEqual({}, @setAlignStack(16));
27 try testing.expectEqual({}, @setCold(true));
28 try testing.expectEqual({}, @setEvalBranchQuota(0));
29 try testing.expectEqual({}, @setFloatMode(.Optimized));
30 try testing.expectEqual({}, @setRuntimeSafety(true));
31 try testing.expectEqual(noreturn, @TypeOf(if (true) @trap() else {}));
32}