authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-03 14:58:46-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-05-03 14:58:46-04:00
log3cfde183f3700999eac0b84b54cae0a7d63743a9
tree57665cd311d115c3fac2b69dfff58939b6ff8592
parent6317da8da400e40a947f6333d1afc289ec349102
parentaa3c3f66da630cddc12931e7845f4e71acbc4860
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11571 from ziglang/stage2-test-behavior

progress towards stage2 behavior tests for all targets passing with the LLVM backend

19 files changed, 190 insertions(+), 111 deletions(-)

lib/std/os/windows.zig+40-10
...@@ -2693,7 +2693,10 @@ pub const MEM_RESERVE_PLACEHOLDERS = 0x2;...@@ -2693,7 +2693,10 @@ pub const MEM_RESERVE_PLACEHOLDERS = 0x2;
2693pub const MEM_DECOMMIT = 0x4000;2693pub const MEM_DECOMMIT = 0x4000;
2694pub const MEM_RELEASE = 0x8000;2694pub const MEM_RELEASE = 0x8000;
26952695
2696pub const PTHREAD_START_ROUTINE = fn (LPVOID) callconv(.C) DWORD;2696pub const PTHREAD_START_ROUTINE = switch (builtin.zig_backend) {
2697 .stage1 => fn (LPVOID) callconv(.C) DWORD,
2698 else => *const fn (LPVOID) callconv(.C) DWORD,
2699};
2697pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;2700pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;
26982701
2699pub const WIN32_FIND_DATAW = extern struct {2702pub const WIN32_FIND_DATAW = extern struct {
...@@ -2866,7 +2869,10 @@ pub const IMAGE_TLS_DIRECTORY = extern struct {...@@ -2866,7 +2869,10 @@ pub const IMAGE_TLS_DIRECTORY = extern struct {
2866pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY;2869pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY;
2867pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY;2870pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY;
28682871
2869pub const PIMAGE_TLS_CALLBACK = ?fn (PVOID, DWORD, PVOID) callconv(.C) void;2872pub const PIMAGE_TLS_CALLBACK = switch (builtin.zig_backend) {
2873 .stage1 => ?fn (PVOID, DWORD, PVOID) callconv(.C) void,
2874 else => ?*const fn (PVOID, DWORD, PVOID) callconv(.C) void,
2875};
28702876
2871pub const PROV_RSA_FULL = 1;2877pub const PROV_RSA_FULL = 1;
28722878
...@@ -2892,7 +2898,10 @@ pub const FILE_ACTION_MODIFIED = 0x00000003;...@@ -2892,7 +2898,10 @@ pub const FILE_ACTION_MODIFIED = 0x00000003;
2892pub const FILE_ACTION_RENAMED_OLD_NAME = 0x00000004;2898pub const FILE_ACTION_RENAMED_OLD_NAME = 0x00000004;
2893pub const FILE_ACTION_RENAMED_NEW_NAME = 0x00000005;2899pub const FILE_ACTION_RENAMED_NEW_NAME = 0x00000005;
28942900
2895pub const LPOVERLAPPED_COMPLETION_ROUTINE = ?fn (DWORD, DWORD, *OVERLAPPED) callconv(.C) void;2901pub const LPOVERLAPPED_COMPLETION_ROUTINE = switch (builtin.zig_backend) {
2902 .stage1 => ?fn (DWORD, DWORD, *OVERLAPPED) callconv(.C) void,
2903 else => ?*const fn (DWORD, DWORD, *OVERLAPPED) callconv(.C) void,
2904};
28962905
2897pub const FILE_NOTIFY_CHANGE_CREATION = 64;2906pub const FILE_NOTIFY_CHANGE_CREATION = 64;
2898pub const FILE_NOTIFY_CHANGE_SIZE = 8;2907pub const FILE_NOTIFY_CHANGE_SIZE = 8;
...@@ -2945,7 +2954,10 @@ pub const RTL_CRITICAL_SECTION = extern struct {...@@ -2945,7 +2954,10 @@ pub const RTL_CRITICAL_SECTION = extern struct {
2945pub const CRITICAL_SECTION = RTL_CRITICAL_SECTION;2954pub const CRITICAL_SECTION = RTL_CRITICAL_SECTION;
2946pub const INIT_ONCE = RTL_RUN_ONCE;2955pub const INIT_ONCE = RTL_RUN_ONCE;
2947pub const INIT_ONCE_STATIC_INIT = RTL_RUN_ONCE_INIT;2956pub const INIT_ONCE_STATIC_INIT = RTL_RUN_ONCE_INIT;
2948pub const INIT_ONCE_FN = fn (InitOnce: *INIT_ONCE, Parameter: ?*anyopaque, Context: ?*anyopaque) callconv(.C) BOOL;2957pub const INIT_ONCE_FN = switch (builtin.zig_backend) {
2958 .stage1 => fn (InitOnce: *INIT_ONCE, Parameter: ?*anyopaque, Context: ?*anyopaque) callconv(.C) BOOL,
2959 else => *const fn (InitOnce: *INIT_ONCE, Parameter: ?*anyopaque, Context: ?*anyopaque) callconv(.C) BOOL,
2960};
29492961
2950pub const RTL_RUN_ONCE = extern struct {2962pub const RTL_RUN_ONCE = extern struct {
2951 Ptr: ?*anyopaque,2963 Ptr: ?*anyopaque,
...@@ -3230,7 +3242,10 @@ pub const EXCEPTION_POINTERS = extern struct {...@@ -3230,7 +3242,10 @@ pub const EXCEPTION_POINTERS = extern struct {
3230 ContextRecord: *std.os.windows.CONTEXT,3242 ContextRecord: *std.os.windows.CONTEXT,
3231};3243};
32323244
3233pub const VECTORED_EXCEPTION_HANDLER = fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(WINAPI) c_long;3245pub const VECTORED_EXCEPTION_HANDLER = switch (builtin.zig_backend) {
3246 .stage1 => fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(WINAPI) c_long,
3247 else => *const fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(WINAPI) c_long,
3248};
32343249
3235pub const OBJECT_ATTRIBUTES = extern struct {3250pub const OBJECT_ATTRIBUTES = extern struct {
3236 Length: ULONG,3251 Length: ULONG,
...@@ -3506,7 +3521,10 @@ pub const RTL_DRIVE_LETTER_CURDIR = extern struct {...@@ -3506,7 +3521,10 @@ pub const RTL_DRIVE_LETTER_CURDIR = extern struct {
3506 DosPath: UNICODE_STRING,3521 DosPath: UNICODE_STRING,
3507};3522};
35083523
3509pub const PPS_POST_PROCESS_INIT_ROUTINE = ?fn () callconv(.C) void;3524pub const PPS_POST_PROCESS_INIT_ROUTINE = switch (builtin.zig_backend) {
3525 .stage1 => ?fn () callconv(.C) void,
3526 else => ?*const fn () callconv(.C) void,
3527};
35103528
3511pub const FILE_BOTH_DIR_INFORMATION = extern struct {3529pub const FILE_BOTH_DIR_INFORMATION = extern struct {
3512 NextEntryOffset: ULONG,3530 NextEntryOffset: ULONG,
...@@ -3526,7 +3544,10 @@ pub const FILE_BOTH_DIR_INFORMATION = extern struct {...@@ -3526,7 +3544,10 @@ pub const FILE_BOTH_DIR_INFORMATION = extern struct {
3526};3544};
3527pub const FILE_BOTH_DIRECTORY_INFORMATION = FILE_BOTH_DIR_INFORMATION;3545pub const FILE_BOTH_DIRECTORY_INFORMATION = FILE_BOTH_DIR_INFORMATION;
35283546
3529pub const IO_APC_ROUTINE = fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.C) void;3547pub const IO_APC_ROUTINE = switch (builtin.zig_backend) {
3548 .stage1 => fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.C) void,
3549 else => *const fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.C) void,
3550};
35303551
3531pub const CURDIR = extern struct {3552pub const CURDIR = extern struct {
3532 DosPath: UNICODE_STRING,3553 DosPath: UNICODE_STRING,
...@@ -3598,8 +3619,14 @@ pub const ENUM_PAGE_FILE_INFORMATION = extern struct {...@@ -3598,8 +3619,14 @@ pub const ENUM_PAGE_FILE_INFORMATION = extern struct {
3598 PeakUsage: SIZE_T,3619 PeakUsage: SIZE_T,
3599};3620};
36003621
3601pub const PENUM_PAGE_FILE_CALLBACKW = ?fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCWSTR) callconv(.C) BOOL;3622pub const PENUM_PAGE_FILE_CALLBACKW = switch (builtin.zig_backend) {
3602pub const PENUM_PAGE_FILE_CALLBACKA = ?fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCSTR) callconv(.C) BOOL;3623 .stage1 => ?fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCWSTR) callconv(.C) BOOL,
3624 else => ?*const fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCWSTR) callconv(.C) BOOL,
3625};
3626pub const PENUM_PAGE_FILE_CALLBACKA = switch (builtin.zig_backend) {
3627 .stage1 => ?fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCSTR) callconv(.C) BOOL,
3628 else => ?*const fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCSTR) callconv(.C) BOOL,
3629};
36033630
3604pub const PSAPI_WS_WATCH_INFORMATION_EX = extern struct {3631pub const PSAPI_WS_WATCH_INFORMATION_EX = extern struct {
3605 BasicInfo: PSAPI_WS_WATCH_INFORMATION,3632 BasicInfo: PSAPI_WS_WATCH_INFORMATION,
...@@ -3699,4 +3726,7 @@ pub const CTRL_CLOSE_EVENT: DWORD = 2;...@@ -3699,4 +3726,7 @@ pub const CTRL_CLOSE_EVENT: DWORD = 2;
3699pub const CTRL_LOGOFF_EVENT: DWORD = 5;3726pub const CTRL_LOGOFF_EVENT: DWORD = 5;
3700pub const CTRL_SHUTDOWN_EVENT: DWORD = 6;3727pub const CTRL_SHUTDOWN_EVENT: DWORD = 6;
37013728
3702pub const HANDLER_ROUTINE = fn (dwCtrlType: DWORD) callconv(.C) BOOL;3729pub const HANDLER_ROUTINE = switch (builtin.zig_backend) {
3730 .stage1 => fn (dwCtrlType: DWORD) callconv(.C) BOOL,
3731 else => *const fn (dwCtrlType: DWORD) callconv(.C) BOOL,
3732};
lib/std/pdb.zig+25-25
...@@ -14,7 +14,7 @@ const ArrayList = std.ArrayList;...@@ -14,7 +14,7 @@ const ArrayList = std.ArrayList;
14// documentation and/or contributors.14// documentation and/or contributors.
1515
16// https://llvm.org/docs/PDB/DbiStream.html#stream-header16// https://llvm.org/docs/PDB/DbiStream.html#stream-header
17pub const DbiStreamHeader = packed struct {17pub const DbiStreamHeader = extern struct {
18 VersionSignature: i32,18 VersionSignature: i32,
19 VersionHeader: u32,19 VersionHeader: u32,
20 Age: u32,20 Age: u32,
...@@ -37,7 +37,7 @@ pub const DbiStreamHeader = packed struct {...@@ -37,7 +37,7 @@ pub const DbiStreamHeader = packed struct {
37 Padding: u32,37 Padding: u32,
38};38};
3939
40pub const SectionContribEntry = packed struct {40pub const SectionContribEntry = extern struct {
41 /// COFF Section index, 1-based41 /// COFF Section index, 1-based
42 Section: u16,42 Section: u16,
43 Padding1: [2]u8,43 Padding1: [2]u8,
...@@ -50,7 +50,7 @@ pub const SectionContribEntry = packed struct {...@@ -50,7 +50,7 @@ pub const SectionContribEntry = packed struct {
50 RelocCrc: u32,50 RelocCrc: u32,
51};51};
5252
53pub const ModInfo = packed struct {53pub const ModInfo = extern struct {
54 Unused1: u32,54 Unused1: u32,
55 SectionContr: SectionContribEntry,55 SectionContr: SectionContribEntry,
56 Flags: u16,56 Flags: u16,
...@@ -68,7 +68,7 @@ pub const ModInfo = packed struct {...@@ -68,7 +68,7 @@ pub const ModInfo = packed struct {
68 //ObjFileName: char[],68 //ObjFileName: char[],
69};69};
7070
71pub const SectionMapHeader = packed struct {71pub const SectionMapHeader = extern struct {
72 /// Number of segment descriptors72 /// Number of segment descriptors
73 Count: u16,73 Count: u16,
7474
...@@ -76,7 +76,7 @@ pub const SectionMapHeader = packed struct {...@@ -76,7 +76,7 @@ pub const SectionMapHeader = packed struct {
76 LogCount: u16,76 LogCount: u16,
77};77};
7878
79pub const SectionMapEntry = packed struct {79pub const SectionMapEntry = extern struct {
80 /// See the SectionMapEntryFlags enum below.80 /// See the SectionMapEntryFlags enum below.
81 Flags: u16,81 Flags: u16,
8282
...@@ -310,7 +310,7 @@ pub const SymbolKind = enum(u16) {...@@ -310,7 +310,7 @@ pub const SymbolKind = enum(u16) {
310310
311pub const TypeIndex = u32;311pub const TypeIndex = u32;
312312
313pub const ProcSym = packed struct {313pub const ProcSym = extern struct {
314 Parent: u32,314 Parent: u32,
315 End: u32,315 End: u32,
316 Next: u32,316 Next: u32,
...@@ -342,7 +342,7 @@ pub const SectionContrSubstreamVersion = enum(u32) {...@@ -342,7 +342,7 @@ pub const SectionContrSubstreamVersion = enum(u32) {
342 _,342 _,
343};343};
344344
345pub const RecordPrefix = packed struct {345pub const RecordPrefix = extern struct {
346 /// Record length, starting from &RecordKind.346 /// Record length, starting from &RecordKind.
347 RecordLen: u16,347 RecordLen: u16,
348348
...@@ -354,7 +354,7 @@ pub const RecordPrefix = packed struct {...@@ -354,7 +354,7 @@ pub const RecordPrefix = packed struct {
354/// The structure definition follows.354/// The structure definition follows.
355/// LineBlockFragmentHeader Blocks[]355/// LineBlockFragmentHeader Blocks[]
356/// Each `LineBlockFragmentHeader` as specified below.356/// Each `LineBlockFragmentHeader` as specified below.
357pub const LineFragmentHeader = packed struct {357pub const LineFragmentHeader = extern struct {
358 /// Code offset of line contribution.358 /// Code offset of line contribution.
359 RelocOffset: u32,359 RelocOffset: u32,
360360
...@@ -376,7 +376,7 @@ pub const LineFlags = packed struct {...@@ -376,7 +376,7 @@ pub const LineFlags = packed struct {
376/// header. The structure definitions follow.376/// header. The structure definitions follow.
377/// LineNumberEntry Lines[NumLines];377/// LineNumberEntry Lines[NumLines];
378/// ColumnNumberEntry Columns[NumLines];378/// ColumnNumberEntry Columns[NumLines];
379pub const LineBlockFragmentHeader = packed struct {379pub const LineBlockFragmentHeader = extern struct {
380 /// Offset of FileChecksum entry in File380 /// Offset of FileChecksum entry in File
381 /// checksums buffer. The checksum entry then381 /// checksums buffer. The checksum entry then
382 /// contains another offset into the string382 /// contains another offset into the string
...@@ -388,7 +388,7 @@ pub const LineBlockFragmentHeader = packed struct {...@@ -388,7 +388,7 @@ pub const LineBlockFragmentHeader = packed struct {
388 BlockSize: u32,388 BlockSize: u32,
389};389};
390390
391pub const LineNumberEntry = packed struct {391pub const LineNumberEntry = extern struct {
392 /// Offset to start of code bytes for line number392 /// Offset to start of code bytes for line number
393 Offset: u32,393 Offset: u32,
394 Flags: u32,394 Flags: u32,
...@@ -404,13 +404,13 @@ pub const LineNumberEntry = packed struct {...@@ -404,13 +404,13 @@ pub const LineNumberEntry = packed struct {
404 };404 };
405};405};
406406
407pub const ColumnNumberEntry = packed struct {407pub const ColumnNumberEntry = extern struct {
408 StartColumn: u16,408 StartColumn: u16,
409 EndColumn: u16,409 EndColumn: u16,
410};410};
411411
412/// Checksum bytes follow.412/// Checksum bytes follow.
413pub const FileChecksumEntryHeader = packed struct {413pub const FileChecksumEntryHeader = extern struct {
414 /// Byte offset of filename in global string table.414 /// Byte offset of filename in global string table.
415 FileNameOffset: u32,415 FileNameOffset: u32,
416416
...@@ -441,7 +441,7 @@ pub const DebugSubsectionKind = enum(u32) {...@@ -441,7 +441,7 @@ pub const DebugSubsectionKind = enum(u32) {
441 CoffSymbolRVA = 0xfd,441 CoffSymbolRVA = 0xfd,
442};442};
443443
444pub const DebugSubsectionHeader = packed struct {444pub const DebugSubsectionHeader = extern struct {
445 /// codeview::DebugSubsectionKind enum445 /// codeview::DebugSubsectionKind enum
446 Kind: DebugSubsectionKind,446 Kind: DebugSubsectionKind,
447447
...@@ -449,7 +449,7 @@ pub const DebugSubsectionHeader = packed struct {...@@ -449,7 +449,7 @@ pub const DebugSubsectionHeader = packed struct {
449 Length: u32,449 Length: u32,
450};450};
451451
452pub const PDBStringTableHeader = packed struct {452pub const PDBStringTableHeader = extern struct {
453 /// PDBStringTableSignature453 /// PDBStringTableSignature
454 Signature: u32,454 Signature: u32,
455455
...@@ -686,12 +686,12 @@ pub const Pdb = struct {...@@ -686,12 +686,12 @@ pub const Pdb = struct {
686686
687 var symbol_i: usize = 0;687 var symbol_i: usize = 0;
688 while (symbol_i != module.symbols.len) {688 while (symbol_i != module.symbols.len) {
689 const prefix = @ptrCast(*RecordPrefix, &module.symbols[symbol_i]);689 const prefix = @ptrCast(*align(1) RecordPrefix, &module.symbols[symbol_i]);
690 if (prefix.RecordLen < 2)690 if (prefix.RecordLen < 2)
691 return null;691 return null;
692 switch (prefix.RecordKind) {692 switch (prefix.RecordKind) {
693 .S_LPROC32, .S_GPROC32 => {693 .S_LPROC32, .S_GPROC32 => {
694 const proc_sym = @ptrCast(*ProcSym, &module.symbols[symbol_i + @sizeOf(RecordPrefix)]);694 const proc_sym = @ptrCast(*align(1) ProcSym, &module.symbols[symbol_i + @sizeOf(RecordPrefix)]);
695 if (address >= proc_sym.CodeOffset and address < proc_sym.CodeOffset + proc_sym.CodeSize) {695 if (address >= proc_sym.CodeOffset and address < proc_sym.CodeOffset + proc_sym.CodeSize) {
696 return mem.sliceTo(@ptrCast([*:0]u8, proc_sym) + @sizeOf(ProcSym), 0);696 return mem.sliceTo(@ptrCast([*:0]u8, proc_sym) + @sizeOf(ProcSym), 0);
697 }697 }
...@@ -712,7 +712,7 @@ pub const Pdb = struct {...@@ -712,7 +712,7 @@ pub const Pdb = struct {
712 var skip_len: usize = undefined;712 var skip_len: usize = undefined;
713 const checksum_offset = module.checksum_offset orelse return error.MissingDebugInfo;713 const checksum_offset = module.checksum_offset orelse return error.MissingDebugInfo;
714 while (sect_offset != subsect_info.len) : (sect_offset += skip_len) {714 while (sect_offset != subsect_info.len) : (sect_offset += skip_len) {
715 const subsect_hdr = @ptrCast(*DebugSubsectionHeader, &subsect_info[sect_offset]);715 const subsect_hdr = @ptrCast(*align(1) DebugSubsectionHeader, &subsect_info[sect_offset]);
716 skip_len = subsect_hdr.Length;716 skip_len = subsect_hdr.Length;
717 sect_offset += @sizeOf(DebugSubsectionHeader);717 sect_offset += @sizeOf(DebugSubsectionHeader);
718718
...@@ -720,7 +720,7 @@ pub const Pdb = struct {...@@ -720,7 +720,7 @@ pub const Pdb = struct {
720 .Lines => {720 .Lines => {
721 var line_index = sect_offset;721 var line_index = sect_offset;
722722
723 const line_hdr = @ptrCast(*LineFragmentHeader, &subsect_info[line_index]);723 const line_hdr = @ptrCast(*align(1) LineFragmentHeader, &subsect_info[line_index]);
724 if (line_hdr.RelocSegment == 0)724 if (line_hdr.RelocSegment == 0)
725 return error.MissingDebugInfo;725 return error.MissingDebugInfo;
726 line_index += @sizeOf(LineFragmentHeader);726 line_index += @sizeOf(LineFragmentHeader);
...@@ -734,7 +734,7 @@ pub const Pdb = struct {...@@ -734,7 +734,7 @@ pub const Pdb = struct {
734 const subsection_end_index = sect_offset + subsect_hdr.Length;734 const subsection_end_index = sect_offset + subsect_hdr.Length;
735735
736 while (line_index < subsection_end_index) {736 while (line_index < subsection_end_index) {
737 const block_hdr = @ptrCast(*LineBlockFragmentHeader, &subsect_info[line_index]);737 const block_hdr = @ptrCast(*align(1) LineBlockFragmentHeader, &subsect_info[line_index]);
738 line_index += @sizeOf(LineBlockFragmentHeader);738 line_index += @sizeOf(LineBlockFragmentHeader);
739 const start_line_index = line_index;739 const start_line_index = line_index;
740740
...@@ -746,7 +746,7 @@ pub const Pdb = struct {...@@ -746,7 +746,7 @@ pub const Pdb = struct {
746 // This is done with a simple linear search.746 // This is done with a simple linear search.
747 var line_i: u32 = 0;747 var line_i: u32 = 0;
748 while (line_i < block_hdr.NumLines) : (line_i += 1) {748 while (line_i < block_hdr.NumLines) : (line_i += 1) {
749 const line_num_entry = @ptrCast(*LineNumberEntry, &subsect_info[line_index]);749 const line_num_entry = @ptrCast(*align(1) LineNumberEntry, &subsect_info[line_index]);
750 line_index += @sizeOf(LineNumberEntry);750 line_index += @sizeOf(LineNumberEntry);
751751
752 const vaddr_start = frag_vaddr_start + line_num_entry.Offset;752 const vaddr_start = frag_vaddr_start + line_num_entry.Offset;
...@@ -758,7 +758,7 @@ pub const Pdb = struct {...@@ -758,7 +758,7 @@ pub const Pdb = struct {
758 // line_i == 0 would mean that no matching LineNumberEntry was found.758 // line_i == 0 would mean that no matching LineNumberEntry was found.
759 if (line_i > 0) {759 if (line_i > 0) {
760 const subsect_index = checksum_offset + block_hdr.NameIndex;760 const subsect_index = checksum_offset + block_hdr.NameIndex;
761 const chksum_hdr = @ptrCast(*FileChecksumEntryHeader, &module.subsect_info[subsect_index]);761 const chksum_hdr = @ptrCast(*align(1) FileChecksumEntryHeader, &module.subsect_info[subsect_index]);
762 const strtab_offset = @sizeOf(PDBStringTableHeader) + chksum_hdr.FileNameOffset;762 const strtab_offset = @sizeOf(PDBStringTableHeader) + chksum_hdr.FileNameOffset;
763 try self.string_table.?.seekTo(strtab_offset);763 try self.string_table.?.seekTo(strtab_offset);
764 const source_file_name = try self.string_table.?.reader().readUntilDelimiterAlloc(self.allocator, 0, 1024);764 const source_file_name = try self.string_table.?.reader().readUntilDelimiterAlloc(self.allocator, 0, 1024);
...@@ -768,12 +768,12 @@ pub const Pdb = struct {...@@ -768,12 +768,12 @@ pub const Pdb = struct {
768 const column = if (has_column) blk: {768 const column = if (has_column) blk: {
769 const start_col_index = start_line_index + @sizeOf(LineNumberEntry) * block_hdr.NumLines;769 const start_col_index = start_line_index + @sizeOf(LineNumberEntry) * block_hdr.NumLines;
770 const col_index = start_col_index + @sizeOf(ColumnNumberEntry) * line_entry_idx;770 const col_index = start_col_index + @sizeOf(ColumnNumberEntry) * line_entry_idx;
771 const col_num_entry = @ptrCast(*ColumnNumberEntry, &subsect_info[col_index]);771 const col_num_entry = @ptrCast(*align(1) ColumnNumberEntry, &subsect_info[col_index]);
772 break :blk col_num_entry.StartColumn;772 break :blk col_num_entry.StartColumn;
773 } else 0;773 } else 0;
774774
775 const found_line_index = start_line_index + line_entry_idx * @sizeOf(LineNumberEntry);775 const found_line_index = start_line_index + line_entry_idx * @sizeOf(LineNumberEntry);
776 const line_num_entry = @ptrCast(*LineNumberEntry, &subsect_info[found_line_index]);776 const line_num_entry = @ptrCast(*align(1) LineNumberEntry, &subsect_info[found_line_index]);
777 const flags = @ptrCast(*LineNumberEntry.Flags, &line_num_entry.Flags);777 const flags = @ptrCast(*LineNumberEntry.Flags, &line_num_entry.Flags);
778778
779 return debug.LineInfo{779 return debug.LineInfo{
...@@ -833,7 +833,7 @@ pub const Pdb = struct {...@@ -833,7 +833,7 @@ pub const Pdb = struct {
833 var sect_offset: usize = 0;833 var sect_offset: usize = 0;
834 var skip_len: usize = undefined;834 var skip_len: usize = undefined;
835 while (sect_offset != mod.subsect_info.len) : (sect_offset += skip_len) {835 while (sect_offset != mod.subsect_info.len) : (sect_offset += skip_len) {
836 const subsect_hdr = @ptrCast(*DebugSubsectionHeader, &mod.subsect_info[sect_offset]);836 const subsect_hdr = @ptrCast(*align(1) DebugSubsectionHeader, &mod.subsect_info[sect_offset]);
837 skip_len = subsect_hdr.Length;837 skip_len = subsect_hdr.Length;
838 sect_offset += @sizeOf(DebugSubsectionHeader);838 sect_offset += @sizeOf(DebugSubsectionHeader);
839839
...@@ -969,7 +969,7 @@ fn blockCountFromSize(size: u32, block_size: u32) u32 {...@@ -969,7 +969,7 @@ fn blockCountFromSize(size: u32, block_size: u32) u32 {
969}969}
970970
971// https://llvm.org/docs/PDB/MsfFile.html#the-superblock971// https://llvm.org/docs/PDB/MsfFile.html#the-superblock
972const SuperBlock = packed struct {972const SuperBlock = extern struct {
973 /// The LLVM docs list a space between C / C++ but empirically this is not the case.973 /// The LLVM docs list a space between C / C++ but empirically this is not the case.
974 const file_magic = "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53\x00\x00\x00";974 const file_magic = "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53\x00\x00\x00";
975975
lib/std/special/test_runner.zig+1-1
...@@ -28,7 +28,7 @@ pub fn main() void {...@@ -28,7 +28,7 @@ pub fn main() void {
28 {28 {
29 return main2() catch @panic("test failure");29 return main2() catch @panic("test failure");
30 }30 }
31 if (builtin.zig_backend == .stage1) processArgs();31 processArgs();
32 const test_fn_list = builtin.test_functions;32 const test_fn_list = builtin.test_functions;
33 var ok_count: usize = 0;33 var ok_count: usize = 0;
34 var skip_count: usize = 0;34 var skip_count: usize = 0;
lib/std/start.zig+1-3
...@@ -29,9 +29,7 @@ comptime {...@@ -29,9 +29,7 @@ comptime {
29 builtin.zig_backend == .stage2_aarch64 or29 builtin.zig_backend == .stage2_aarch64 or
30 builtin.zig_backend == .stage2_arm or30 builtin.zig_backend == .stage2_arm or
31 builtin.zig_backend == .stage2_riscv64 or31 builtin.zig_backend == .stage2_riscv64 or
32 builtin.zig_backend == .stage2_sparcv9 or32 builtin.zig_backend == .stage2_sparcv9)
33 (builtin.zig_backend == .stage2_llvm and native_os != .linux and native_os != .macos) or
34 (builtin.zig_backend == .stage2_llvm and native_arch != .x86_64 and native_arch != .aarch64))
35 {33 {
36 if (builtin.output_mode == .Exe) {34 if (builtin.output_mode == .Exe) {
37 if ((builtin.link_libc or builtin.object_format == .c) and @hasDecl(root, "main")) {35 if ((builtin.link_libc or builtin.object_format == .c) and @hasDecl(root, "main")) {
src/Air.zig+2
...@@ -815,6 +815,8 @@ pub const VectorCmp = struct {...@@ -815,6 +815,8 @@ pub const VectorCmp = struct {
815/// 1. `Inst.Ref` for every inputs_len815/// 1. `Inst.Ref` for every inputs_len
816/// 2. for every outputs_len816/// 2. for every outputs_len
817/// - constraint: memory at this position is reinterpreted as a null817/// - constraint: memory at this position is reinterpreted as a null
818/// terminated string.
819/// - name: memory at this position is reinterpreted as a null
818/// terminated string. pad to the next u32 after the null byte.820/// terminated string. pad to the next u32 after the null byte.
819/// 3. for every inputs_len821/// 3. for every inputs_len
820/// - constraint: memory at this position is reinterpreted as a null822/// - constraint: memory at this position is reinterpreted as a null
src/Sema.zig+14-6
...@@ -4323,7 +4323,7 @@ pub fn analyzeExport(...@@ -4323,7 +4323,7 @@ pub fn analyzeExport(
4323 const exported_decl = mod.declPtr(exported_decl_index);4323 const exported_decl = mod.declPtr(exported_decl_index);
4324 // TODO run the same checks as we do for C ABI struct fields4324 // TODO run the same checks as we do for C ABI struct fields
4325 switch (exported_decl.ty.zigTypeTag()) {4325 switch (exported_decl.ty.zigTypeTag()) {
4326 .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float => {},4326 .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float, .Pointer, .Optional => {},
4327 else => return sema.fail(block, src, "unable to export type '{}'", .{4327 else => return sema.fail(block, src, "unable to export type '{}'", .{
4328 exported_decl.ty.fmt(sema.mod),4328 exported_decl.ty.fmt(sema.mod),
4329 }),4329 }),
...@@ -10535,7 +10535,11 @@ fn zirAsm(...@@ -10535,7 +10535,11 @@ fn zirAsm(
10535 var output_type_bits = extra.data.output_type_bits;10535 var output_type_bits = extra.data.output_type_bits;
10536 var needed_capacity: usize = @typeInfo(Air.Asm).Struct.fields.len + outputs_len + inputs_len;10536 var needed_capacity: usize = @typeInfo(Air.Asm).Struct.fields.len + outputs_len + inputs_len;
1053710537
10538 const Output = struct { constraint: []const u8, ty: Type };10538 const Output = struct {
10539 constraint: []const u8,
10540 name: []const u8,
10541 ty: Type,
10542 };
10539 const output: ?Output = if (outputs_len == 0) null else blk: {10543 const output: ?Output = if (outputs_len == 0) null else blk: {
10540 const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i);10544 const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i);
10541 extra_i = output.end;10545 extra_i = output.end;
...@@ -10548,10 +10552,12 @@ fn zirAsm(...@@ -10548,10 +10552,12 @@ fn zirAsm(
10548 }10552 }
1054910553
10550 const constraint = sema.code.nullTerminatedString(output.data.constraint);10554 const constraint = sema.code.nullTerminatedString(output.data.constraint);
10551 needed_capacity += constraint.len / 4 + 1;10555 const name = sema.code.nullTerminatedString(output.data.name);
10556 needed_capacity += (constraint.len + name.len + (2 + 3)) / 4;
1055210557
10553 break :blk Output{10558 break :blk Output{
10554 .constraint = constraint,10559 .constraint = constraint,
10560 .name = name,
10555 .ty = try sema.resolveType(block, ret_ty_src, output.data.operand),10561 .ty = try sema.resolveType(block, ret_ty_src, output.data.operand),
10556 };10562 };
10557 };10563 };
...@@ -10573,7 +10579,7 @@ fn zirAsm(...@@ -10573,7 +10579,7 @@ fn zirAsm(
1057310579
10574 const constraint = sema.code.nullTerminatedString(input.data.constraint);10580 const constraint = sema.code.nullTerminatedString(input.data.constraint);
10575 const name = sema.code.nullTerminatedString(input.data.name);10581 const name = sema.code.nullTerminatedString(input.data.name);
10576 needed_capacity += (constraint.len + name.len + 1) / 4 + 1;10582 needed_capacity += (constraint.len + name.len + (2 + 3)) / 4;
10577 inputs[arg_i] = .{ .c = constraint, .n = name };10583 inputs[arg_i] = .{ .c = constraint, .n = name };
10578 }10584 }
1057910585
...@@ -10611,7 +10617,9 @@ fn zirAsm(...@@ -10611,7 +10617,9 @@ fn zirAsm(
10611 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());10617 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
10612 mem.copy(u8, buffer, o.constraint);10618 mem.copy(u8, buffer, o.constraint);
10613 buffer[o.constraint.len] = 0;10619 buffer[o.constraint.len] = 0;
10614 sema.air_extra.items.len += o.constraint.len / 4 + 1;10620 mem.copy(u8, buffer[o.constraint.len + 1 ..], o.name);
10621 buffer[o.constraint.len + 1 + o.name.len] = 0;
10622 sema.air_extra.items.len += (o.constraint.len + o.name.len + (2 + 3)) / 4;
10615 }10623 }
10616 for (inputs) |input| {10624 for (inputs) |input| {
10617 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());10625 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
...@@ -10619,7 +10627,7 @@ fn zirAsm(...@@ -10619,7 +10627,7 @@ fn zirAsm(
10619 buffer[input.c.len] = 0;10627 buffer[input.c.len] = 0;
10620 mem.copy(u8, buffer[input.c.len + 1 ..], input.n);10628 mem.copy(u8, buffer[input.c.len + 1 ..], input.n);
10621 buffer[input.c.len + 1 + input.n.len] = 0;10629 buffer[input.c.len + 1 + input.n.len] = 0;
10622 sema.air_extra.items.len += (input.c.len + input.n.len + 1) / 4 + 1;10630 sema.air_extra.items.len += (input.c.len + input.n.len + (2 + 3)) / 4;
10623 }10631 }
10624 for (clobbers) |clobber| {10632 for (clobbers) |clobber| {
10625 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());10633 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
src/arch/aarch64/CodeGen.zig+5-3
...@@ -3272,10 +3272,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -3272,10 +3272,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
3272 if (output != .none) {3272 if (output != .none) {
3273 return self.fail("TODO implement codegen for non-expr asm", .{});3273 return self.fail("TODO implement codegen for non-expr asm", .{});
3274 }3274 }
3275 const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
3275 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);3276 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
3277 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
3276 // This equation accounts for the fact that even if we have exactly 4 bytes3278 // This equation accounts for the fact that even if we have exactly 4 bytes
3277 // for the string, we still use the next u32 for the null terminator.3279 // for the string, we still use the next u32 for the null terminator.
3278 extra_i += constraint.len / 4 + 1;3280 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
32793281
3280 break constraint;3282 break constraint;
3281 } else null;3283 } else null;
...@@ -3283,10 +3285,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -3283,10 +3285,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
3283 for (inputs) |input| {3285 for (inputs) |input| {
3284 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);3286 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
3285 const constraint = std.mem.sliceTo(input_bytes, 0);3287 const constraint = std.mem.sliceTo(input_bytes, 0);
3286 const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);3288 const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);
3287 // This equation accounts for the fact that even if we have exactly 4 bytes3289 // This equation accounts for the fact that even if we have exactly 4 bytes
3288 // for the string, we still use the next u32 for the null terminator.3290 // for the string, we still use the next u32 for the null terminator.
3289 extra_i += (constraint.len + input_name.len + 1) / 4 + 1;3291 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
32903292
3291 if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {3293 if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {
3292 return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});3294 return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});
src/arch/arm/CodeGen.zig+5-3
...@@ -4078,10 +4078,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -4078,10 +4078,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
4078 if (output != .none) {4078 if (output != .none) {
4079 return self.fail("TODO implement codegen for non-expr asm", .{});4079 return self.fail("TODO implement codegen for non-expr asm", .{});
4080 }4080 }
4081 const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
4081 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);4082 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
4083 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
4082 // This equation accounts for the fact that even if we have exactly 4 bytes4084 // This equation accounts for the fact that even if we have exactly 4 bytes
4083 // for the string, we still use the next u32 for the null terminator.4085 // for the string, we still use the next u32 for the null terminator.
4084 extra_i += constraint.len / 4 + 1;4086 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
40854087
4086 break constraint;4088 break constraint;
4087 } else null;4089 } else null;
...@@ -4089,10 +4091,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -4089,10 +4091,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
4089 for (inputs) |input| {4091 for (inputs) |input| {
4090 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);4092 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
4091 const constraint = std.mem.sliceTo(input_bytes, 0);4093 const constraint = std.mem.sliceTo(input_bytes, 0);
4092 const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);4094 const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);
4093 // This equation accounts for the fact that even if we have exactly 4 bytes4095 // This equation accounts for the fact that even if we have exactly 4 bytes
4094 // for the string, we still use the next u32 for the null terminator.4096 // for the string, we still use the next u32 for the null terminator.
4095 extra_i += (constraint.len + input_name.len + 1) / 4 + 1;4097 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
40964098
4097 if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {4099 if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {
4098 return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});4100 return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});
src/arch/riscv64/CodeGen.zig+5-3
...@@ -2098,10 +2098,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -2098,10 +2098,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
2098 if (output != .none) {2098 if (output != .none) {
2099 return self.fail("TODO implement codegen for non-expr asm", .{});2099 return self.fail("TODO implement codegen for non-expr asm", .{});
2100 }2100 }
2101 const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
2101 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);2102 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
2103 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
2102 // This equation accounts for the fact that even if we have exactly 4 bytes2104 // This equation accounts for the fact that even if we have exactly 4 bytes
2103 // for the string, we still use the next u32 for the null terminator.2105 // for the string, we still use the next u32 for the null terminator.
2104 extra_i += constraint.len / 4 + 1;2106 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
21052107
2106 break constraint;2108 break constraint;
2107 } else null;2109 } else null;
...@@ -2109,10 +2111,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -2109,10 +2111,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
2109 for (inputs) |input| {2111 for (inputs) |input| {
2110 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);2112 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
2111 const constraint = std.mem.sliceTo(input_bytes, 0);2113 const constraint = std.mem.sliceTo(input_bytes, 0);
2112 const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);2114 const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);
2113 // This equation accounts for the fact that even if we have exactly 4 bytes2115 // This equation accounts for the fact that even if we have exactly 4 bytes
2114 // for the string, we still use the next u32 for the null terminator.2116 // for the string, we still use the next u32 for the null terminator.
2115 extra_i += (constraint.len + input_name.len + 1) / 4 + 1;2117 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
21162118
2117 if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {2119 if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {
2118 return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});2120 return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});
src/arch/sparcv9/CodeGen.zig+5-3
...@@ -642,10 +642,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -642,10 +642,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
642 if (output != .none) {642 if (output != .none) {
643 return self.fail("TODO implement codegen for non-expr asm", .{});643 return self.fail("TODO implement codegen for non-expr asm", .{});
644 }644 }
645 const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
645 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);646 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
647 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
646 // This equation accounts for the fact that even if we have exactly 4 bytes648 // This equation accounts for the fact that even if we have exactly 4 bytes
647 // for the string, we still use the next u32 for the null terminator.649 // for the string, we still use the next u32 for the null terminator.
648 extra_i += constraint.len / 4 + 1;650 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
649651
650 break constraint;652 break constraint;
651 } else null;653 } else null;
...@@ -653,10 +655,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -653,10 +655,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
653 for (inputs) |input| {655 for (inputs) |input| {
654 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);656 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
655 const constraint = std.mem.sliceTo(input_bytes, 0);657 const constraint = std.mem.sliceTo(input_bytes, 0);
656 const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);658 const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);
657 // This equation accounts for the fact that even if we have exactly 4 bytes659 // This equation accounts for the fact that even if we have exactly 4 bytes
658 // for the string, we still use the next u32 for the null terminator.660 // for the string, we still use the next u32 for the null terminator.
659 extra_i += (constraint.len + input_name.len + 1) / 4 + 1;661 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
660662
661 if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {663 if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {
662 return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});664 return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});
src/arch/x86_64/CodeGen.zig+5-3
...@@ -4738,10 +4738,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -4738,10 +4738,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
4738 if (output != .none) {4738 if (output != .none) {
4739 return self.fail("TODO implement codegen for non-expr asm", .{});4739 return self.fail("TODO implement codegen for non-expr asm", .{});
4740 }4740 }
4741 const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
4741 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);4742 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
4743 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
4742 // This equation accounts for the fact that even if we have exactly 4 bytes4744 // This equation accounts for the fact that even if we have exactly 4 bytes
4743 // for the string, we still use the next u32 for the null terminator.4745 // for the string, we still use the next u32 for the null terminator.
4744 extra_i += constraint.len / 4 + 1;4746 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
47454747
4746 break constraint;4748 break constraint;
4747 } else null;4749 } else null;
...@@ -4749,10 +4751,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -4749,10 +4751,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
4749 for (inputs) |input| {4751 for (inputs) |input| {
4750 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);4752 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
4751 const constraint = std.mem.sliceTo(input_bytes, 0);4753 const constraint = std.mem.sliceTo(input_bytes, 0);
4752 const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);4754 const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);
4753 // This equation accounts for the fact that even if we have exactly 4 bytes4755 // This equation accounts for the fact that even if we have exactly 4 bytes
4754 // for the string, we still use the next u32 for the null terminator.4756 // for the string, we still use the next u32 for the null terminator.
4755 extra_i += (constraint.len + input_name.len + 1) / 4 + 1;4757 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
47564758
4757 if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {4759 if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {
4758 return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});4760 return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});
src/codegen/c.zig+7-3
...@@ -3018,10 +3018,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3018,10 +3018,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3018 if (output != .none) {3018 if (output != .none) {
3019 return f.fail("TODO implement codegen for non-expr asm", .{});3019 return f.fail("TODO implement codegen for non-expr asm", .{});
3020 }3020 }
3021 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
3021 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);3022 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);
3023 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
3022 // This equation accounts for the fact that even if we have exactly 4 bytes3024 // This equation accounts for the fact that even if we have exactly 4 bytes
3023 // for the string, we still use the next u32 for the null terminator.3025 // for the string, we still use the next u32 for the null terminator.
3024 extra_i += constraint.len / 4 + 1;3026 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
30253027
3026 break constraint;3028 break constraint;
3027 } else null;3029 } else null;
...@@ -3031,10 +3033,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3031,10 +3033,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
30313033
3032 const inputs_extra_begin = extra_i;3034 const inputs_extra_begin = extra_i;
3033 for (inputs) |input, i| {3035 for (inputs) |input, i| {
3034 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);3036 const input_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
3037 const constraint = std.mem.sliceTo(input_bytes, 0);
3038 const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);
3035 // This equation accounts for the fact that even if we have exactly 4 bytes3039 // This equation accounts for the fact that even if we have exactly 4 bytes
3036 // for the string, we still use the next u32 for the null terminator.3040 // for the string, we still use the next u32 for the null terminator.
3037 extra_i += constraint.len / 4 + 1;3041 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
30383042
3039 if (constraint[0] == '{' and constraint[constraint.len - 1] == '}') {3043 if (constraint[0] == '{' and constraint[constraint.len - 1] == '}') {
3040 const reg = constraint[1 .. constraint.len - 1];3044 const reg = constraint[1 .. constraint.len - 1];
src/codegen/llvm.zig+41-20
...@@ -340,6 +340,10 @@ pub const Object = struct {...@@ -340,6 +340,10 @@ pub const Object = struct {
340340
341 llvm_module.setModuleDataLayout(target_data);341 llvm_module.setModuleDataLayout(target_data);
342342
343 if (options.pic) llvm_module.setModulePICLevel();
344 if (options.pie) llvm_module.setModulePIELevel();
345 if (code_model != .Default) llvm_module.setModuleCodeModel(code_model);
346
343 return Object{347 return Object{
344 .gpa = gpa,348 .gpa = gpa,
345 .module = options.module.?,349 .module = options.module.?,
...@@ -4577,6 +4581,10 @@ pub const FuncGen = struct {...@@ -4577,6 +4581,10 @@ pub const FuncGen = struct {
4577 const operand_ty = self.air.typeOf(pl_op.operand);4581 const operand_ty = self.air.typeOf(pl_op.operand);
4578 const name = self.air.nullTerminatedString(pl_op.payload);4582 const name = self.air.nullTerminatedString(pl_op.payload);
45794583
4584 if (needDbgVarWorkaround(self.dg, operand_ty)) {
4585 return null;
4586 }
4587
4580 const di_local_var = dib.createAutoVariable(4588 const di_local_var = dib.createAutoVariable(
4581 self.di_scope.?,4589 self.di_scope.?,
4582 name.ptr,4590 name.ptr,
...@@ -4638,14 +4646,19 @@ pub const FuncGen = struct {...@@ -4638,14 +4646,19 @@ pub const FuncGen = struct {
4638 var llvm_param_i: usize = 0;4646 var llvm_param_i: usize = 0;
4639 var total_i: usize = 0;4647 var total_i: usize = 0;
46404648
4649 var name_map: std.StringArrayHashMapUnmanaged(void) = .{};
4650 try name_map.ensureUnusedCapacity(arena, outputs.len + inputs.len);
4651
4641 for (outputs) |output| {4652 for (outputs) |output| {
4642 if (output != .none) {4653 if (output != .none) {
4643 return self.todo("implement inline asm with non-returned output", .{});4654 return self.todo("implement inline asm with non-returned output", .{});
4644 }4655 }
4656 const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
4645 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);4657 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
4658 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
4646 // This equation accounts for the fact that even if we have exactly 4 bytes4659 // This equation accounts for the fact that even if we have exactly 4 bytes
4647 // for the string, we still use the next u32 for the null terminator.4660 // for the string, we still use the next u32 for the null terminator.
4648 extra_i += constraint.len / 4 + 1;4661 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
46494662
4650 try llvm_constraints.ensureUnusedCapacity(self.gpa, constraint.len + 1);4663 try llvm_constraints.ensureUnusedCapacity(self.gpa, constraint.len + 1);
4651 if (total_i != 0) {4664 if (total_i != 0) {
...@@ -4654,17 +4667,17 @@ pub const FuncGen = struct {...@@ -4654,17 +4667,17 @@ pub const FuncGen = struct {
4654 llvm_constraints.appendAssumeCapacity('=');4667 llvm_constraints.appendAssumeCapacity('=');
4655 llvm_constraints.appendSliceAssumeCapacity(constraint[1..]);4668 llvm_constraints.appendSliceAssumeCapacity(constraint[1..]);
46564669
4670 name_map.putAssumeCapacityNoClobber(name, {});
4657 total_i += 1;4671 total_i += 1;
4658 }4672 }
46594673
4660 const input_start_extra_i = extra_i;
4661 for (inputs) |input| {4674 for (inputs) |input| {
4662 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);4675 const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
4663 const constraint = std.mem.sliceTo(input_bytes, 0);4676 const constraint = std.mem.sliceTo(extra_bytes, 0);
4664 const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);4677 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
4665 // This equation accounts for the fact that even if we have exactly 4 bytes4678 // This equation accounts for the fact that even if we have exactly 4 bytes
4666 // for the string, we still use the next u32 for the null terminator.4679 // for the string, we still use the next u32 for the null terminator.
4667 extra_i += (constraint.len + input_name.len + 1) / 4 + 1;4680 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
46684681
4669 const arg_llvm_value = try self.resolveInst(input);4682 const arg_llvm_value = try self.resolveInst(input);
46704683
...@@ -4677,6 +4690,7 @@ pub const FuncGen = struct {...@@ -4677,6 +4690,7 @@ pub const FuncGen = struct {
4677 }4690 }
4678 llvm_constraints.appendSliceAssumeCapacity(constraint);4691 llvm_constraints.appendSliceAssumeCapacity(constraint);
46794692
4693 name_map.putAssumeCapacityNoClobber(name, {});
4680 llvm_param_i += 1;4694 llvm_param_i += 1;
4681 total_i += 1;4695 total_i += 1;
4682 }4696 }
...@@ -4739,20 +4753,11 @@ pub const FuncGen = struct {...@@ -4739,20 +4753,11 @@ pub const FuncGen = struct {
4739 const name = asm_source[name_start..i];4753 const name = asm_source[name_start..i];
4740 state = .start;4754 state = .start;
47414755
4742 extra_i = input_start_extra_i;4756 const index = name_map.getIndex(name) orelse {
4743 for (inputs) |_, input_i| {4757 // we should validate the assembly in Sema; by now it is too late
4744 const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);4758 return self.todo("unknown input or output name: '{s}'", .{name});
4745 const constraint = std.mem.sliceTo(input_bytes, 0);4759 };
4746 const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);4760 try rendered_template.writer().print("{d}", .{index});
4747 extra_i += (constraint.len + input_name.len + 1) / 4 + 1;
4748
4749 if (std.mem.eql(u8, name, input_name)) {
4750 try rendered_template.writer().print("{d}", .{input_i});
4751 break;
4752 }
4753 } else {
4754 return self.todo("TODO validate asm in Sema", .{});
4755 }
4756 },4761 },
4757 else => {},4762 else => {},
4758 },4763 },
...@@ -6150,6 +6155,10 @@ pub const FuncGen = struct {...@@ -6150,6 +6155,10 @@ pub const FuncGen = struct {
61506155
6151 const inst_ty = self.air.typeOfIndex(inst);6156 const inst_ty = self.air.typeOfIndex(inst);
6152 if (self.dg.object.di_builder) |dib| {6157 if (self.dg.object.di_builder) |dib| {
6158 if (needDbgVarWorkaround(self.dg, inst_ty)) {
6159 return arg_val;
6160 }
6161
6153 const src_index = self.getSrcArgIndex(self.arg_index - 1);6162 const src_index = self.getSrcArgIndex(self.arg_index - 1);
6154 const func = self.dg.decl.getFunction().?;6163 const func = self.dg.decl.getFunction().?;
6155 const lbrace_line = self.dg.module.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;6164 const lbrace_line = self.dg.module.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
...@@ -8251,3 +8260,15 @@ const AnnotatedDITypePtr = enum(usize) {...@@ -8251,3 +8260,15 @@ const AnnotatedDITypePtr = enum(usize) {
8251};8260};
82528261
8253const lt_errors_fn_name = "__zig_lt_errors_len";8262const lt_errors_fn_name = "__zig_lt_errors_len";
8263
8264/// Without this workaround, LLVM crashes with "unknown codeview register H1"
8265/// TODO use llvm-reduce and file upstream LLVM bug for this.
8266fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool {
8267 if (ty.tag() == .f16) {
8268 const target = dg.module.getTarget();
8269 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
8270 return true;
8271 }
8272 }
8273 return false;
8274}
src/codegen/llvm/bindings.zig+9
...@@ -310,6 +310,15 @@ pub const Module = opaque {...@@ -310,6 +310,15 @@ pub const Module = opaque {
310 pub const setModuleDataLayout = LLVMSetModuleDataLayout;310 pub const setModuleDataLayout = LLVMSetModuleDataLayout;
311 extern fn LLVMSetModuleDataLayout(*const Module, *const TargetData) void;311 extern fn LLVMSetModuleDataLayout(*const Module, *const TargetData) void;
312312
313 pub const setModulePICLevel = ZigLLVMSetModulePICLevel;
314 extern fn ZigLLVMSetModulePICLevel(module: *const Module) void;
315
316 pub const setModulePIELevel = ZigLLVMSetModulePIELevel;
317 extern fn ZigLLVMSetModulePIELevel(module: *const Module) void;
318
319 pub const setModuleCodeModel = ZigLLVMSetModuleCodeModel;
320 extern fn ZigLLVMSetModuleCodeModel(module: *const Module, code_model: CodeModel) void;
321
313 pub const addFunction = LLVMAddFunction;322 pub const addFunction = LLVMAddFunction;
314 extern fn LLVMAddFunction(*const Module, Name: [*:0]const u8, FunctionTy: *const Type) *const Value;323 extern fn LLVMAddFunction(*const Module, Name: [*:0]const u8, FunctionTy: *const Type) *const Value;
315324
src/print_air.zig+18-10
...@@ -542,15 +542,19 @@ const Writer = struct {...@@ -542,15 +542,19 @@ const Writer = struct {
542 extra_i += inputs.len;542 extra_i += inputs.len;
543543
544 for (outputs) |output| {544 for (outputs) |output| {
545 const constraint = w.air.nullTerminatedString(extra_i);545 const extra_bytes = std.mem.sliceAsBytes(w.air.extra[extra_i..]);
546 const constraint = std.mem.sliceTo(extra_bytes, 0);
547 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
548
546 // This equation accounts for the fact that even if we have exactly 4 bytes549 // This equation accounts for the fact that even if we have exactly 4 bytes
547 // for the string, we still use the next u32 for the null terminator.550 // for the strings and their null terminators, we still use the next u32
548 extra_i += constraint.len / 4 + 1;551 // for the null terminator.
552 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
549553
550 if (output == .none) {554 if (output == .none) {
551 try s.print(", -> {s}", .{constraint});555 try s.print(", [{s}] -> {s}", .{ name, constraint });
552 } else {556 } else {
553 try s.print(", out {s} = (", .{constraint});557 try s.print(", [{s}] out {s} = (", .{ name, constraint });
554 try w.writeOperand(s, inst, op_index, output);558 try w.writeOperand(s, inst, op_index, output);
555 op_index += 1;559 op_index += 1;
556 try s.writeByte(')');560 try s.writeByte(')');
...@@ -558,12 +562,15 @@ const Writer = struct {...@@ -558,12 +562,15 @@ const Writer = struct {
558 }562 }
559563
560 for (inputs) |input| {564 for (inputs) |input| {
561 const constraint = w.air.nullTerminatedString(extra_i);565 const extra_bytes = std.mem.sliceAsBytes(w.air.extra[extra_i..]);
566 const constraint = std.mem.sliceTo(extra_bytes, 0);
567 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
562 // This equation accounts for the fact that even if we have exactly 4 bytes568 // This equation accounts for the fact that even if we have exactly 4 bytes
563 // for the string, we still use the next u32 for the null terminator.569 // for the strings and their null terminators, we still use the next u32
564 extra_i += constraint.len / 4 + 1;570 // for the null terminator.
571 extra_i += (constraint.len + name.len + 1) / 4 + 1;
565572
566 try s.print(", in {s} = (", .{constraint});573 try s.print(", [{s}] in {s} = (", .{ name, constraint });
567 try w.writeOperand(s, inst, op_index, input);574 try w.writeOperand(s, inst, op_index, input);
568 op_index += 1;575 op_index += 1;
569 try s.writeByte(')');576 try s.writeByte(')');
...@@ -572,7 +579,8 @@ const Writer = struct {...@@ -572,7 +579,8 @@ const Writer = struct {
572 {579 {
573 var clobber_i: u32 = 0;580 var clobber_i: u32 = 0;
574 while (clobber_i < clobbers_len) : (clobber_i += 1) {581 while (clobber_i < clobbers_len) : (clobber_i += 1) {
575 const clobber = w.air.nullTerminatedString(extra_i);582 const extra_bytes = std.mem.sliceAsBytes(w.air.extra[extra_i..]);
583 const clobber = std.mem.sliceTo(extra_bytes, 0);
576 // This equation accounts for the fact that even if we have exactly 4 bytes584 // This equation accounts for the fact that even if we have exactly 4 bytes
577 // for the string, we still use the next u32 for the null terminator.585 // for the string, we still use the next u32 for the null terminator.
578 extra_i += clobber.len / 4 + 1;586 extra_i += clobber.len / 4 + 1;
test/behavior/struct.zig+4-15
...@@ -421,21 +421,10 @@ test "packed struct 24bits" {...@@ -421,21 +421,10 @@ test "packed struct 24bits" {
421 if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO421 if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO
422422
423 comptime {423 comptime {
424 // TODO Remove if and leave only the else branch when it is also fixed in stage2424 // stage1 gets the wrong answer for sizeof
425 if (builtin.zig_backend == .stage2_llvm or builtin.zig_backend == .stage2_x86 or425 if (builtin.zig_backend != .stage1) {
426 builtin.zig_backend == .stage2_riscv64)426 std.debug.assert(@sizeOf(Foo24Bits) == @sizeOf(u24));
427 {427 std.debug.assert(@sizeOf(Foo96Bits) == @sizeOf(u96));
428 // Stage 2 still expects the wrong values
429 try expect(@sizeOf(Foo24Bits) == 4);
430 if (@sizeOf(usize) == 4) {
431 try expect(@sizeOf(Foo96Bits) == 12);
432 } else {
433 try expect(@sizeOf(Foo96Bits) == 16);
434 }
435 } else {
436 // Stage1 is now fixed and is expected to return right values
437 try expectEqual(@sizeOf(Foo24Bits), 3);
438 try expectEqual(@sizeOf(Foo96Bits), 12);
439 }428 }
440 }429 }
441430
test/incremental/aarch64-macos/hello_world_with_updates.0.zig+1-1
...@@ -2,4 +2,4 @@...@@ -2,4 +2,4 @@
2// output_mode=Exe2// output_mode=Exe
3// target=aarch64-macos3// target=aarch64-macos
4//4//
5// :109:9: error: struct 'tmp.tmp' has no member named 'main'5// :107:9: error: struct 'tmp.tmp' has no member named 'main'
test/incremental/x86_64-linux/hello_world_with_updates.0.zig+1-1
...@@ -2,4 +2,4 @@...@@ -2,4 +2,4 @@
2// output_mode=Exe2// output_mode=Exe
3// target=x86_64-linux3// target=x86_64-linux
4//4//
5// :109:9: error: struct 'tmp.tmp' has no member named 'main'5// :107:9: error: struct 'tmp.tmp' has no member named 'main'
test/incremental/x86_64-macos/hello_world_with_updates.0.zig+1-1
...@@ -2,4 +2,4 @@...@@ -2,4 +2,4 @@
2// output_mode=Exe2// output_mode=Exe
3// target=x86_64-macos3// target=x86_64-macos
4//4//
5// :109:9: error: struct 'tmp.tmp' has no member named 'main'5// :107:9: error: struct 'tmp.tmp' has no member named 'main'