@@ -30,7 +30,7 @@ fn cWriterWrite(c_file: *std.c.FILE, bytes: []const u8) std.fs.File.WriteError!u
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
test "C Writer" {
|
||||
if (!builtin.link_libc or builtin.os.tag == .wasi) return error.SkipZigTest;
|
||||
|
||||
const filename = "tmp_io_test_file.txt";
|
||||
|
||||
@@ -2831,6 +2831,8 @@ pub fn asBytes(ptr: anytype) AsBytesReturnType(@TypeOf(ptr)) {
|
||||
}
|
||||
|
||||
test "asBytes" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
|
||||
const deadbeef = @as(u32, 0xDEADBEEF);
|
||||
const deadbeef_bytes = switch (native_endian) {
|
||||
.Big => "\xDE\xAD\xBE\xEF",
|
||||
@@ -2857,7 +2859,14 @@ test "asBytes" {
|
||||
.c = 0xDE,
|
||||
.d = 0xA1,
|
||||
};
|
||||
try testing.expect(eql(u8, asBytes(&inst), "\xBE\xEF\xDE\xA1"));
|
||||
switch (native_endian) {
|
||||
.Little => {
|
||||
try testing.expect(eql(u8, asBytes(&inst), "\xBE\xEF\xDE\xA1"));
|
||||
},
|
||||
.Big => {
|
||||
try testing.expect(eql(u8, asBytes(&inst), "\xA1\xDE\xEF\xBE"));
|
||||
},
|
||||
}
|
||||
|
||||
const ZST = struct {};
|
||||
const zero = ZST{};
|
||||
@@ -2917,6 +2926,8 @@ pub fn bytesAsValue(comptime T: type, bytes: anytype) BytesAsValueReturnType(T,
|
||||
}
|
||||
|
||||
test "bytesAsValue" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
|
||||
const deadbeef = @as(u32, 0xDEADBEEF);
|
||||
const deadbeef_bytes = switch (native_endian) {
|
||||
.Big => "\xDE\xAD\xBE\xEF",
|
||||
@@ -2948,7 +2959,10 @@ test "bytesAsValue" {
|
||||
.c = 0xDE,
|
||||
.d = 0xA1,
|
||||
};
|
||||
const inst_bytes = "\xBE\xEF\xDE\xA1";
|
||||
const inst_bytes = switch (native_endian) {
|
||||
.Little => "\xBE\xEF\xDE\xA1",
|
||||
.Big => "\xA1\xDE\xEF\xBE",
|
||||
};
|
||||
const inst2 = bytesAsValue(S, inst_bytes);
|
||||
try testing.expect(meta.eql(inst, inst2.*));
|
||||
}
|
||||
@@ -3115,6 +3129,8 @@ test "sliceAsBytes with sentinel slice" {
|
||||
}
|
||||
|
||||
test "sliceAsBytes packed struct at runtime and comptime" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
|
||||
const Foo = packed struct {
|
||||
a: u4,
|
||||
b: u4,
|
||||
@@ -3124,16 +3140,8 @@ test "sliceAsBytes packed struct at runtime and comptime" {
|
||||
var foo: Foo = undefined;
|
||||
var slice = sliceAsBytes(@as(*[1]Foo, &foo)[0..1]);
|
||||
slice[0] = 0x13;
|
||||
switch (native_endian) {
|
||||
.Big => {
|
||||
try testing.expect(foo.a == 0x1);
|
||||
try testing.expect(foo.b == 0x3);
|
||||
},
|
||||
.Little => {
|
||||
try testing.expect(foo.a == 0x3);
|
||||
try testing.expect(foo.b == 0x1);
|
||||
},
|
||||
}
|
||||
try testing.expect(foo.a == 0x3);
|
||||
try testing.expect(foo.b == 0x1);
|
||||
}
|
||||
};
|
||||
try S.doTheTest();
|
||||
|
||||
@@ -706,12 +706,8 @@ fn expectFail(expected_error: anyerror, data: anytype, filter: []Insn) !void {
|
||||
}
|
||||
|
||||
test "simulator coverage" {
|
||||
const some_data: packed struct {
|
||||
foo: u32,
|
||||
bar: u8,
|
||||
} = .{
|
||||
.foo = mem.nativeToBig(u32, 0xaabbccdd),
|
||||
.bar = 0x7f,
|
||||
const some_data = [_]u8{
|
||||
0xaa, 0xbb, 0xcc, 0xdd, 0x7f,
|
||||
};
|
||||
|
||||
try expectPass(&some_data, &.{
|
||||
@@ -764,7 +760,7 @@ test "simulator coverage" {
|
||||
// ld #len
|
||||
// fail if A != 5
|
||||
Insn.ld_len(),
|
||||
Insn.jmp(.jeq, .{ .k = @sizeOf(@TypeOf(some_data)) }, 1, 0),
|
||||
Insn.jmp(.jeq, .{ .k = some_data.len }, 1, 0),
|
||||
Insn.ret(.{ .k = 9 }),
|
||||
// ld #0
|
||||
// ld arc4random()
|
||||
|
||||
@@ -7096,6 +7096,7 @@ fn funcCommon(
|
||||
if (param.ty.tag() == .generic_poison) is_generic = true;
|
||||
}
|
||||
|
||||
var destroy_fn_on_error = false;
|
||||
const new_func: *Module.Fn = new_func: {
|
||||
if (!has_body) break :new_func undefined;
|
||||
if (sema.comptime_args_fn_inst == func_inst) {
|
||||
@@ -7103,9 +7104,10 @@ fn funcCommon(
|
||||
sema.preallocated_new_func = null; // take ownership
|
||||
break :new_func new_func;
|
||||
}
|
||||
destroy_fn_on_error = true;
|
||||
break :new_func try sema.gpa.create(Module.Fn);
|
||||
};
|
||||
errdefer if (has_body) sema.gpa.destroy(new_func);
|
||||
errdefer if (destroy_fn_on_error) sema.gpa.destroy(new_func);
|
||||
|
||||
var maybe_inferred_error_set_node: ?*Module.Fn.InferredErrorSetListNode = null;
|
||||
errdefer if (maybe_inferred_error_set_node) |node| sema.gpa.destroy(node);
|
||||
|
||||
@@ -5244,7 +5244,7 @@ pub const FuncGen = struct {
|
||||
const operand_ty = self.air.typeOf(pl_op.operand);
|
||||
const name = self.air.nullTerminatedString(pl_op.payload);
|
||||
|
||||
if (needDbgVarWorkaround(self.dg, operand_ty)) {
|
||||
if (needDbgVarWorkaround(self.dg)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -5432,6 +5432,25 @@ pub const FuncGen = struct {
|
||||
total_i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// For some targets, Clang unconditionally adds some clobbers to all inline assembly.
|
||||
// While this is probably not strictly necessary, if we don't follow Clang's lead
|
||||
// here then we may risk tripping LLVM bugs since anything not used by Clang tends
|
||||
// to be buggy and regress often.
|
||||
switch (target.cpu.arch) {
|
||||
.x86_64, .i386 => {
|
||||
if (total_i != 0) try llvm_constraints.append(self.gpa, ',');
|
||||
try llvm_constraints.appendSlice(self.gpa, "~{dirflag},~{fpsr},~{flags}");
|
||||
total_i += 3;
|
||||
},
|
||||
.mips, .mipsel, .mips64, .mips64el => {
|
||||
if (total_i != 0) try llvm_constraints.append(self.gpa, ',');
|
||||
try llvm_constraints.appendSlice(self.gpa, "~{$1}");
|
||||
total_i += 1;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
const asm_source = std.mem.sliceAsBytes(self.air.extra[extra_i..])[0..extra.data.source_len];
|
||||
|
||||
// hackety hacks until stage2 has proper inline asm in the frontend.
|
||||
@@ -6988,7 +7007,7 @@ pub const FuncGen = struct {
|
||||
|
||||
const inst_ty = self.air.typeOfIndex(inst);
|
||||
if (self.dg.object.di_builder) |dib| {
|
||||
if (needDbgVarWorkaround(self.dg, inst_ty)) {
|
||||
if (needDbgVarWorkaround(self.dg)) {
|
||||
return arg_val;
|
||||
}
|
||||
|
||||
@@ -9255,13 +9274,11 @@ const AnnotatedDITypePtr = enum(usize) {
|
||||
const lt_errors_fn_name = "__zig_lt_errors_len";
|
||||
|
||||
/// Without this workaround, LLVM crashes with "unknown codeview register H1"
|
||||
/// TODO use llvm-reduce and file upstream LLVM bug for this.
|
||||
fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool {
|
||||
if (ty.tag() == .f16) {
|
||||
const target = dg.module.getTarget();
|
||||
if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
|
||||
return true;
|
||||
}
|
||||
/// https://github.com/llvm/llvm-project/issues/56484
|
||||
fn needDbgVarWorkaround(dg: *DeclGen) bool {
|
||||
const target = dg.module.getTarget();
|
||||
if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1134,6 +1134,7 @@ void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module) {
|
||||
}
|
||||
|
||||
void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module) {
|
||||
unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION);
|
||||
unwrap(module)->addModuleFlag(Module::Warning, "CodeView", 1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user