zig

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

commit 65e74dfbda3e50ba09a2b59061ccb90a7dd68e9f (tree)
parent 508cbec69455d82c0e9bb5ae47f064ab33460469
Author: Ali Cheraghi <alichraghi@proton.me>
Date:   Wed, 17 Jun 2026 01:54:10 +0330

@extern: add flat decoration

Diffstat:
Mlib/std/lang.zig | 3++-
Msrc/InternPool.zig | 8++++----
Msrc/Sema.zig | 7+++++++
Msrc/codegen/spirv/Assembler.zig | 9+++++++++
Msrc/codegen/spirv/CodeGen.zig | 40++++++++++++++++++++++++++++++----------
Mtest/behavior/basic.zig | 4++++
Mtest/behavior/bitcast.zig | 3+++
Mtest/behavior/cast.zig | 13+++++++++++++
Mtest/behavior/cast_int.zig | 4++++
Mtest/behavior/enum.zig | 6++++++
Mtest/behavior/error.zig | 10++++++++++
Mtest/behavior/eval.zig | 1-
Mtest/behavior/floatop.zig | 8++++++++
Mtest/behavior/fn.zig | 6++++++
Mtest/behavior/math.zig | 2+-
Mtest/behavior/maximum_minimum.zig | 1+
Mtest/behavior/memcpy.zig | 1-
Mtest/behavior/muladd.zig | 3+++
Mtest/behavior/optional.zig | 1+
Mtest/behavior/packed-struct.zig | 3+++
Mtest/behavior/struct.zig | 3+++
Mtest/behavior/vector.zig | 2++
Mtest/behavior/while.zig | 1-
Atest/cases/compile_errors/extern_spirv_decoration_validation.zig | 13+++++++++++++
24 files changed, 133 insertions(+), 19 deletions(-)

diff --git a/lib/std/lang.zig b/lib/std/lang.zig @@ -1173,11 +1173,12 @@ pub const ExternOptions = struct { pub const Decoration = union(enum) { location: u32, + flat: u32, descriptor: Descriptor, pub const Descriptor = struct { - binding: u32, set: u32, + binding: u32, }; }; diff --git a/src/InternPool.zig b/src/InternPool.zig @@ -5406,16 +5406,15 @@ pub const Tag = enum(u8) { _: u23 = 0, pub const Source = enum(u1) { builtin, syntax }; - pub const DecorationType = enum(u2) { none, location, descriptor }; + pub const DecorationType = enum(u2) { none, location, descriptor, flat }; }; pub fn decoration(self: Extern) ?std.lang.ExternOptions.Decoration { return switch (self.flags.decoration_type) { .none => null, - .location => std.lang.ExternOptions.Decoration{ - .location = self.location_or_descriptor_set, - }, + .location => std.lang.ExternOptions.Decoration{ .location = self.location_or_descriptor_set }, .descriptor => std.lang.ExternOptions.Decoration{ .descriptor = .{ .set = self.location_or_descriptor_set, .binding = self.descriptor_binding } }, + .flat => std.lang.ExternOptions.Decoration{ .flat = self.location_or_descriptor_set }, }; } }; @@ -9199,6 +9198,7 @@ pub fn getExtern( }) catch unreachable; // capacity asserted above const decoration_type, const location_or_descriptor_set, const descriptor_binding = if (key.decoration) |decoration| switch (decoration) { .location => |location| .{ Tag.Extern.Flags.DecorationType.location, location, undefined }, + .flat => |location| .{ Tag.Extern.Flags.DecorationType.flat, location, undefined }, .descriptor => |descriptor| .{ Tag.Extern.Flags.DecorationType.descriptor, descriptor.set, descriptor.binding }, } else .{ Tag.Extern.Flags.DecorationType.none, undefined, undefined }; const extra_index = addExtraAssumeCapacity(extra, Tag.Extern{ diff --git a/src/Sema.zig b/src/Sema.zig @@ -25021,6 +25021,13 @@ fn zirBuiltinExtern( .pcrel => if (options.visibility == .default) return sema.fail(block, options_src, "cannot require a pc-relative relocation to a symbol with default visibility", .{}), } + if (options.decoration) |decoration| switch (decoration) { + .flat => if (ptr_info.flags.address_space != .input) { + return sema.fail(block, options_src, "'flat' decoration requires 'input' address space", .{}); + }, + .location, .descriptor => {}, + }; + // TODO: error for threadlocal functions, non-const functions, etc const extern_val = try pt.getExtern(.{ diff --git a/src/codegen/spirv/Assembler.zig b/src/codegen/spirv/Assembler.zig @@ -393,6 +393,15 @@ fn processGenericInstruction(ass: *Assembler) !?AsmValue { const actual_word_count = section.instructions.items.len - first_word; section.instructions.items[first_word] |= @as(u32, @as(u16, @intCast(actual_word_count))) << 16 | @intFromEnum(ass.inst.opcode); + switch (ass.inst.opcode) { + .OpKill, + .OpReturn, + .OpReturnValue, + .OpUnreachable, + => ass.cg.block_terminated = true, + else => {}, + } + if (maybe_result_id) |result| return .{ .value = result }; return null; } diff --git a/src/codegen/spirv/CodeGen.zig b/src/codegen/spirv/CodeGen.zig @@ -118,6 +118,10 @@ block_stack: std.ArrayList(*Block) = .empty, block_results: std.AutoHashMapUnmanaged(Air.Inst.Index, Id) = .empty, base_line: u32, block_label: Id = .none, +/// Whether the current block has been terminated by a terminator +/// instruction (e.g. OpKill from inline assembly). When true, no further +/// branch instructions should be emitted for the current block. +block_terminated: bool = false, next_arg_index: u32 = 0, args: std.ArrayList(Id) = .empty, virtual_allocas: std.AutoHashMapUnmanaged(Id, ?Id) = .empty, @@ -428,10 +432,13 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { if (ty.zigTypeTag(zcu) == .@"struct" and storage_class != .physical_storage_buffer) { try cg.module.decorate(ty_id, .block); } - try cg.module.decorate(ptr_ty_id, .{ - .array_stride = .{ .array_stride = @intCast(ty.abiSize(zcu)) }, - }); - try cg.decorateLayout(ty, ty_id); + + if (ty.hasRuntimeBits(zcu)) { + try cg.module.decorate(ptr_ty_id, .{ + .array_stride = .{ .array_stride = @intCast(ty.abiSize(zcu)) }, + }); + try cg.decorateLayout(ty, ty_id); + } }, else => {}, } @@ -445,6 +452,10 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { .location = .{ .location = location }, }); }, + .flat => |location| { + try cg.module.decorate(result_id, .{ .location = .{ .location = location } }); + try cg.module.decorate(result_id, .flat); + }, .descriptor => |descriptor| { if (storage_class != .storage_buffer and storage_class != .uniform and storage_class != .uniform_constant) { return cg.fail("storage class must be one of (storage_buffer, uniform, uniform_constant) but is {s}", .{@tagName(storage_class)}); @@ -770,6 +781,7 @@ fn addFunctionDep(cg: *CodeGen, decl_index: Module.Decl.Index, storage_class: St fn beginSpvBlock(cg: *CodeGen, label: Id) !void { try cg.body.emit(cg.module.gpa, .OpLabel, .{ .id_result = label }); cg.block_label = label; + cg.block_terminated = false; } /// Return the amount of bits in the largest supported integer type. This is either 32 (always supported), or 64 (if @@ -2038,10 +2050,12 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id { const elem_ty: Type = .fromInterned(spirv_type.ty); const elem_ty_id = try cg.resolveType(elem_ty, .indirect); const result_id = try cg.module.runtimeArrayType(ip_index, elem_ty_id); - try cg.module.decorate( - result_id, - .{ .array_stride = .{ .array_stride = @intCast(elem_ty.abiSize(zcu)) } }, - ); + + if (elem_ty.hasRuntimeBits(zcu)) { + try cg.module.decorate(result_id, .{ .array_stride = .{ + .array_stride = @intCast(elem_ty.abiSize(zcu)), + } }); + } return result_id; }, } @@ -6564,6 +6578,8 @@ fn structuredNextBlock(cg: *CodeGen, incoming: []const Block.Incoming) !Id { /// terminating a body, there should be no instructions after it. /// This function should only be called with structured control flow generation. fn structuredBreak(cg: *CodeGen, target_block: Id) !void { + if (cg.block_terminated) return; + const gpa = cg.module.gpa; const sblock = cg.block_stack.getLast().?; const merge_block = switch (sblock.*) { @@ -6833,7 +6849,9 @@ fn airCondBr(cg: *CodeGen, inst: Air.Inst.Index) !void { .next_block = then_next, }; - try cg.body.emit(gpa, .OpBranch, .{ .target_label = merge_label }); + if (!cg.block_terminated) { + try cg.body.emit(gpa, .OpBranch, .{ .target_label = merge_label }); + } try cg.beginSpvBlock(else_label); const else_next = try cg.genStructuredBody(.selection, else_body); @@ -6842,7 +6860,9 @@ fn airCondBr(cg: *CodeGen, inst: Air.Inst.Index) !void { .next_block = else_next, }; - try cg.body.emit(gpa, .OpBranch, .{ .target_label = merge_label }); + if (!cg.block_terminated) { + try cg.body.emit(gpa, .OpBranch, .{ .target_label = merge_label }); + } try cg.beginSpvBlock(merge_label); const next_block = try cg.structuredNextBlock(&.{ then_incoming, else_incoming }); diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig @@ -302,6 +302,8 @@ test "compile time global reinterpret" { } test "cast undefined" { + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + const array: [100]u8 = undefined; const slice = @as([]const u8, &array); testCastUndefined(slice); @@ -372,6 +374,7 @@ test "call function pointer in struct" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; try expect(mem.eql(u8, f3(true), "a")); + try expect(mem.eql(u8, f3(false), "b")); } fn f3(x: bool) []const u8 { @@ -412,6 +415,7 @@ test "call result of if else expression" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; try expect(mem.eql(u8, f2(true), "a")); + try expect(mem.eql(u8, f2(false), "b")); } fn f2(x: bool) []const u8 { return (if (x) &fA else &fB)(); diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig @@ -35,6 +35,8 @@ test "@bitCast iX -> uX exotic integers" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; + const bit_values = [_]usize{ 1, 48, 27, 512, 493, 293, 125, 204, 112 }; inline for (bit_values) |bits| { @@ -77,6 +79,7 @@ test "bitcast uX to bytes" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const bit_values = [_]usize{ 1, 48, 27, 512, 493, 293, 125, 204, 112 }; inline for (bit_values) |bits| { diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig @@ -103,6 +103,10 @@ test "comptime_int @floatFromInt" { } test "@floatFromInt" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + const S = struct { fn doTheTest() !void { try testIntToFloat(-2); @@ -128,9 +132,13 @@ fn testIntFromFloat(comptime F: type, f: F, comptime I: type, i: I) !void { test "@intFromFloat > 128 bits" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + try testIntFromFloat(f16, 1024, u140, 1024); try testIntFromFloat(f16, -1024, i140, -1024); + try testIntFromFloat(f32, 1 << 24, u140, 1 << 24); try testIntFromFloat(f32, -1 << 24, i140, -1 << 24); @@ -152,10 +160,13 @@ test "@floatFromInt > 128 bits" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; try testFloatFromInt(u140, 1024, f16, 1024); + try testFloatFromInt(i140, -1024, f16, -1024); try testFloatFromInt(u140, 1 << 24, f32, 1 << 24); + try testFloatFromInt(i140, -1 << 24, f32, -1 << 24); try testFloatFromInt(u200, 1 << 53, f64, 1 << 53); try testFloatFromInt(i200, -1 << 53, f64, -1 << 53); @@ -416,9 +427,11 @@ test "implicit cast from *[N]T to [*c]T" { var y: [*c]u16 = &x; try expect(std.mem.eql(u16, x[0..4], y[0..4])); + x[0] = 8; y[3] = 6; try expect(std.mem.eql(u16, x[0..4], y[0..4])); } + test "*usize to *void" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; diff --git a/test/behavior/cast_int.zig b/test/behavior/cast_int.zig @@ -8,6 +8,8 @@ const minInt = std.math.minInt; test "@intCast i32 to u7" { 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; + var x: u128 = maxInt(u128); var y: i32 = 120; _ = .{ &x, &y }; @@ -143,6 +145,7 @@ test "@intCast <= 64 bits" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; try testIntCast(i32, minInt(i32), i64, minInt(i32)); + try testIntCast(i32, maxInt(i32), i64, maxInt(i32)); try testIntCast(u32, maxInt(u32), u64, maxInt(u32)); try testIntCast(u32, maxInt(i32), i64, maxInt(i32)); try testIntCast(u32, maxInt(u32), i64, maxInt(u32)); @@ -169,6 +172,7 @@ test "@intCast > 128 bits" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; try testIntCast(u8, 123, u140, 123); + try testIntCast(u64, 1 << 63, u140, 1 << 63); try testIntCast(u127, maxInt(u127), u140, maxInt(u127)); try testIntCast(i8, -42, i140, -42); try testIntCast(i64, minInt(i64), i140, minInt(i64)); diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig @@ -932,6 +932,7 @@ test "constant enum initialization with differing sizes" { if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; try test3_1(test3_foo); + try test3_2(test3_bar); } const Test3Foo = union(enum) { One: void, @@ -972,7 +973,9 @@ test "@tagName" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); } @@ -987,7 +990,9 @@ test "@tagName non-exhaustive enum" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; + try expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B")); comptime assert(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B")); } const NonExhaustive = enum(u8) { A, B, _ }; @@ -1029,6 +1034,7 @@ test "@tagName on enum literals" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; try expect(mem.eql(u8, @tagName(.FooBar), "FooBar")); + comptime assert(mem.eql(u8, @tagName(.FooBar), "FooBar")); } test "tag name with signed enum values" { diff --git a/test/behavior/error.zig b/test/behavior/error.zig @@ -145,11 +145,17 @@ test "implicit cast to optional to error union to return result loc" { } test "fn returning empty error set can be passed as fn returning any error" { + if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + + entry(); + comptime entry(); } test "fn returning empty error set can be passed as fn returning any error - pointer" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + entryPtr(); + comptime entryPtr(); } fn entry() void { foo2(bar2); @@ -362,8 +368,10 @@ test "error: Infer error set from literals" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; _ = nullLiteral("n") catch |err| handleErrors(err); + _ = floatLiteral("n") catch |err| handleErrors(err); _ = intLiteral("n") catch |err| handleErrors(err); _ = comptime nullLiteral("n") catch |err| handleErrors(err); + _ = comptime floatLiteral("n") catch |err| handleErrors(err); _ = comptime intLiteral("n") catch |err| handleErrors(err); } @@ -689,6 +697,7 @@ test "coerce error set to the current inferred error set" { test "error union payload is properly aligned" { 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; const S = struct { a: u128, @@ -746,6 +755,7 @@ test "pointer to error union payload" { 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_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var err_union: anyerror!u8 = 15; diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig @@ -1181,7 +1181,6 @@ test "lazy sizeof is resolved in division" { } test "lazy sizeof union tag size in compare" { - const A = union(enum) { a: void, b: void, diff --git a/test/behavior/floatop.zig b/test/behavior/floatop.zig @@ -134,6 +134,8 @@ test "cmp f32" { } test "cmp f64" { + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + try testCmp(f64); try comptime testCmp(f64); } @@ -142,7 +144,9 @@ test "cmp f128" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + try testCmp(f128); try comptime testCmp(f128); } @@ -150,7 +154,10 @@ test "cmp f80/c_longdouble" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; + try testCmp(f80); + try comptime testCmp(f80); try testCmp(c_longdouble); try comptime testCmp(c_longdouble); } @@ -225,6 +232,7 @@ test "vector cmp f32" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig @@ -292,6 +292,9 @@ fn voidFun(a: i32, b: void, c: i32, d: void) !void { test "call function with empty string" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + + acceptsString(""); } fn acceptsString(foo: []u8) void { @@ -302,7 +305,9 @@ test "function pointers" { 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_spirv) return error.SkipZigTest; + const fns = [_]*const @TypeOf(fn1){ + &fn1, &fn2, &fn3, &fn4, @@ -440,6 +445,7 @@ test "method call with optional and error union first param" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; const S = struct { + x: i32 = 1234, fn opt(s: ?@This()) !void { try expect(s.?.x == 1234); diff --git a/test/behavior/math.zig b/test/behavior/math.zig @@ -574,6 +574,7 @@ test "large integer division" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; { var numerator: u256 = 99999999999999999997315645440; @@ -654,7 +655,6 @@ fn testSignedWrappingEval(x: i32) !void { } test "signed negation wrapping" { - try testSignedNegationWrappingEval(minInt(i16)); try comptime testSignedNegationWrappingEval(minInt(i16)); } diff --git a/test/behavior/maximum_minimum.zig b/test/behavior/maximum_minimum.zig @@ -350,6 +350,7 @@ test "@min/@max with runtime signed and unsigned integers of same size" { test "@min/@max with runtime vectors of signed and unsigned integers of same size" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 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; diff --git a/test/behavior/memcpy.zig b/test/behavior/memcpy.zig @@ -168,7 +168,6 @@ test "@memcpy with sentinel" { } test "@memcpy no sentinel source into sentinel destination" { - const S = struct { fn doTheTest() void { const src: []const u8 = &.{ 1, 2, 3 }; diff --git a/test/behavior/muladd.zig b/test/behavior/muladd.zig @@ -34,6 +34,7 @@ test "@mulAdd f16" { if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; try comptime testMulAdd16(); + try testMulAdd16(); } fn testMulAdd16() !void { @@ -48,7 +49,9 @@ test "@mulAdd f80" { 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_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; + try comptime testMulAdd80(); try testMulAdd80(); } diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig @@ -522,6 +522,7 @@ test "alignment of wrapping an optional payload" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { const I = extern struct { x: i128 }; diff --git a/test/behavior/packed-struct.zig b/test/behavior/packed-struct.zig @@ -227,6 +227,8 @@ test "nested packed structs" { test "regular in irregular packed struct" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Irregular = packed struct { bar: Regular = Regular{}, _: u24 = 0, @@ -247,6 +249,7 @@ test "nested packed struct unaligned" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; const S1 = packed struct { + a: u4, b: u4, c: u8, }; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig @@ -446,6 +446,7 @@ test "runtime struct initialization of bitfield" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 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; const s1 = Nibbles{ .x = x1, @@ -503,6 +504,7 @@ test "implicit cast packed struct field to const ptr" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 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 const LevelUpMove = packed struct { move_id: u9, @@ -536,6 +538,7 @@ test "packed struct with non-ABI-aligned field" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = packed struct { x: u9, diff --git a/test/behavior/vector.zig b/test/behavior/vector.zig @@ -415,6 +415,7 @@ test "vector @splat" { test "load vector elements via comptime index" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const S = struct { @@ -617,6 +618,7 @@ test "vector division operators" { test "vector bitwise not operator" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + 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; diff --git a/test/behavior/while.zig b/test/behavior/while.zig @@ -38,7 +38,6 @@ fn staticWhileLoop2() i32 { } test "while with continue expression" { - var sum: i32 = 0; { var i: i32 = 0; diff --git a/test/cases/compile_errors/extern_spirv_decoration_validation.zig b/test/cases/compile_errors/extern_spirv_decoration_validation.zig @@ -0,0 +1,13 @@ +const x = @extern(*addrspace(.output) u32, .{ + .name = "x", + .decoration = .{ .flat = 0 }, +}); +comptime { + _ = x; +} + +// error +// backend=selfhosted +// target=spirv64-vulkan +// +// :1:45: error: 'flat' decoration requires 'input' address space