From f1ae688d371f49fdbf65f952d655905c74871fdb Mon Sep 17 00:00:00 2001 From: r00ster91 Date: Sun, 5 Mar 2023 15:45:23 +0100 Subject: [PATCH] AstGen: ensure certain builtin functions return void Fixes #14779 Co-authored-by: Veikka Tuominen --- src/AstGen.zig | 32 +++++++++---------- ...n_functions_returning_void_or_noreturn.zig | 32 +++++++++++++++++++ 2 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 test/behavior/builtin_functions_returning_void_or_noreturn.zig diff --git a/src/AstGen.zig b/src/AstGen.zig index 587b574a01..20f4fb6df3 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -8060,35 +8060,35 @@ fn builtinCall( }, .fence => { const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[0]); - const result = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{ + _ = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(node), .operand = order, }); - return rvalue(gz, ri, result, node); + return rvalue(gz, ri, .void_value, node); }, .set_float_mode => { const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .float_mode_type } }, params[0]); - const result = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{ + _ = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(node), .operand = order, }); - return rvalue(gz, ri, result, node); + return rvalue(gz, ri, .void_value, node); }, .set_align_stack => { const order = try expr(gz, scope, align_ri, params[0]); - const result = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{ + _ = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(node), .operand = order, }); - return rvalue(gz, ri, result, node); + return rvalue(gz, ri, .void_value, node); }, .set_cold => { const order = try expr(gz, scope, ri, params[0]); - const result = try gz.addExtendedPayload(.set_cold, Zir.Inst.UnNode{ + _ = try gz.addExtendedPayload(.set_cold, Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(node), .operand = order, }); - return rvalue(gz, ri, result, node); + return rvalue(gz, ri, .void_value, node); }, .src => { @@ -8373,14 +8373,14 @@ fn builtinCall( }, .atomic_store => { const int_type = try typeExpr(gz, scope, params[0]); - const result = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{ + _ = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{ // zig fmt: off .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), .operand = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]), .ordering = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[3]), // zig fmt: on }); - return rvalue(gz, ri, result, node); + return rvalue(gz, ri, .void_value, node); }, .mul_add => { const float_type = try typeExpr(gz, scope, params[0]); @@ -8421,20 +8421,20 @@ fn builtinCall( return rvalue(gz, ri, result, node); }, .memcpy => { - const result = try gz.addPlNode(.memcpy, node, Zir.Inst.Memcpy{ + _ = try gz.addPlNode(.memcpy, node, Zir.Inst.Memcpy{ .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]), .source = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_const_u8_type } }, params[1]), .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]), }); - return rvalue(gz, ri, result, node); + return rvalue(gz, ri, .void_value, node); }, .memset => { - const result = try gz.addPlNode(.memset, node, Zir.Inst.Memset{ + _ = try gz.addPlNode(.memset, node, Zir.Inst.Memset{ .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]), .byte = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u8_type } }, params[1]), .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]), }); - return rvalue(gz, ri, result, node); + return rvalue(gz, ri, .void_value, node); }, .shuffle => { const result = try gz.addPlNode(.shuffle, node, Zir.Inst.Shuffle{ @@ -8475,12 +8475,12 @@ fn builtinCall( .prefetch => { const ptr = try expr(gz, scope, .{ .rl = .none }, params[0]); const options = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .prefetch_options_type } }, params[1]); - const result = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{ + _ = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{ .node = gz.nodeIndexToRelative(node), .lhs = ptr, .rhs = options, }); - return rvalue(gz, ri, result, node); + return rvalue(gz, ri, .void_value, node); }, .c_va_arg => { if (astgen.fn_block == null) { diff --git a/test/behavior/builtin_functions_returning_void_or_noreturn.zig b/test/behavior/builtin_functions_returning_void_or_noreturn.zig new file mode 100644 index 0000000000..072f5576cc --- /dev/null +++ b/test/behavior/builtin_functions_returning_void_or_noreturn.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const testing = std.testing; + +var x: u8 = 1; + +// This excludes builtin functions that return void or noreturn that cannot be tested. +test { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO + + var val: u8 = undefined; + try testing.expectEqual({}, @atomicStore(u8, &val, 0, .Unordered)); + try testing.expectEqual(void, @TypeOf(@breakpoint())); + try testing.expectEqual({}, @export(x, .{ .name = "x" })); + try testing.expectEqual({}, @fence(.Acquire)); + try testing.expectEqual({}, @memcpy(@intToPtr([*]u8, 1), @intToPtr([*]u8, 1), 0)); + try testing.expectEqual({}, @memset(@intToPtr([*]u8, 1), undefined, 0)); + try testing.expectEqual(noreturn, @TypeOf(if (true) @panic("") else {})); + try testing.expectEqual({}, @prefetch(&val, .{})); + try testing.expectEqual({}, @setAlignStack(16)); + try testing.expectEqual({}, @setCold(true)); + try testing.expectEqual({}, @setEvalBranchQuota(0)); + try testing.expectEqual({}, @setFloatMode(.Optimized)); + try testing.expectEqual({}, @setRuntimeSafety(true)); + try testing.expectEqual(noreturn, @TypeOf(if (true) @trap() else {})); +}