diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-07-04 17:22:36 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-07-04 17:22:36 -0700 |
| commit | fbd6c883213ae9fce9734e2702cd6d3ef7691694 (patch) | |
| tree | 54b3178757d827e2756165e123d4526332bc3a3a | |
| parent | f59bd2be539ce736d2ef04d16f48980d9c02a3ab (diff) | |
| parent | 6fc9f6c5f6a067475f97cd16cb265332c8b7c6f3 (diff) | |
| download | zig-fbd6c883213ae9fce9734e2702cd6d3ef7691694.tar.gz zig-fbd6c883213ae9fce9734e2702cd6d3ef7691694.zip | |
Merge remote-tracking branch 'origin/master' into llvm14
| -rw-r--r-- | lib/std/Thread.zig | 3 | ||||
| -rw-r--r-- | src/Sema.zig | 61 | ||||
| -rw-r--r-- | src/codegen/spirv/Section.zig | 10 | ||||
| -rw-r--r-- | src/link/Coff.zig | 153 |
4 files changed, 140 insertions, 87 deletions
diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index aaf0fc3440..d52515b88d 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -513,7 +513,8 @@ const WindowsThreadImpl = struct { errdefer assert(windows.kernel32.HeapFree(heap_handle, 0, alloc_ptr) != 0); const instance_bytes = @ptrCast([*]u8, alloc_ptr)[0..alloc_bytes]; - const instance = std.heap.FixedBufferAllocator.init(instance_bytes).allocator().create(Instance) catch unreachable; + var fba = std.heap.FixedBufferAllocator.init(instance_bytes); + const instance = fba.allocator().create(Instance) catch unreachable; instance.* = .{ .fn_args = args, .thread = .{ diff --git a/src/Sema.zig b/src/Sema.zig index b946e29057..e234255c6e 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -5736,6 +5736,7 @@ fn instantiateGenericCall( const arg_src = call_src; // TODO better source location const arg_ty = sema.typeOf(uncasted_args[i]); const arg_val = try sema.resolveValue(block, arg_src, uncasted_args[i]); + try sema.resolveLazyValue(block, arg_src, arg_val); arg_val.hash(arg_ty, &hasher, mod); if (is_anytype) { arg_ty.hashWithHasher(&hasher, mod); @@ -26079,12 +26080,12 @@ fn intFitsInType( sema: *Sema, block: *Block, src: LazySrcLoc, - self: Value, + val: Value, ty: Type, vector_index: ?*usize, ) CompileError!bool { const target = sema.mod.getTarget(); - switch (self.tag()) { + switch (val.tag()) { .zero, .undef, .bool_false, @@ -26104,30 +26105,38 @@ fn intFitsInType( else => unreachable, }, - .lazy_align => { - const info = ty.intInfo(target); - const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed); - // If it is u16 or bigger we know the alignment fits without resolving it. - if (info.bits >= max_needed_bits) return true; - const x = try sema.typeAbiAlignment(block, src, self.castTag(.lazy_align).?.data); - if (x == 0) return true; - const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); - return info.bits >= actual_needed_bits; + .lazy_align => switch (ty.zigTypeTag()) { + .Int => { + const info = ty.intInfo(target); + const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed); + // If it is u16 or bigger we know the alignment fits without resolving it. + if (info.bits >= max_needed_bits) return true; + const x = try sema.typeAbiAlignment(block, src, val.castTag(.lazy_align).?.data); + if (x == 0) return true; + const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); + return info.bits >= actual_needed_bits; + }, + .ComptimeInt => return true, + else => unreachable, }, - .lazy_size => { - const info = ty.intInfo(target); - const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed); - // If it is u64 or bigger we know the size fits without resolving it. - if (info.bits >= max_needed_bits) return true; - const x = try sema.typeAbiSize(block, src, self.castTag(.lazy_size).?.data); - if (x == 0) return true; - const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); - return info.bits >= actual_needed_bits; + .lazy_size => switch (ty.zigTypeTag()) { + .Int => { + const info = ty.intInfo(target); + const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed); + // If it is u64 or bigger we know the size fits without resolving it. + if (info.bits >= max_needed_bits) return true; + const x = try sema.typeAbiSize(block, src, val.castTag(.lazy_size).?.data); + if (x == 0) return true; + const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); + return info.bits >= actual_needed_bits; + }, + .ComptimeInt => return true, + else => unreachable, }, .int_u64 => switch (ty.zigTypeTag()) { .Int => { - const x = self.castTag(.int_u64).?.data; + const x = val.castTag(.int_u64).?.data; if (x == 0) return true; const info = ty.intInfo(target); const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); @@ -26138,13 +26147,13 @@ fn intFitsInType( }, .int_i64 => switch (ty.zigTypeTag()) { .Int => { - const x = self.castTag(.int_i64).?.data; + const x = val.castTag(.int_i64).?.data; if (x == 0) return true; const info = ty.intInfo(target); if (info.signedness == .unsigned and x < 0) return false; var buffer: Value.BigIntSpace = undefined; - return (try self.toBigIntAdvanced(&buffer, target, sema.kit(block, src))).fitsInTwosComp(info.signedness, info.bits); + return (try val.toBigIntAdvanced(&buffer, target, sema.kit(block, src))).fitsInTwosComp(info.signedness, info.bits); }, .ComptimeInt => return true, else => unreachable, @@ -26152,7 +26161,7 @@ fn intFitsInType( .int_big_positive => switch (ty.zigTypeTag()) { .Int => { const info = ty.intInfo(target); - return self.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); + return val.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); }, .ComptimeInt => return true, else => unreachable, @@ -26160,7 +26169,7 @@ fn intFitsInType( .int_big_negative => switch (ty.zigTypeTag()) { .Int => { const info = ty.intInfo(target); - return self.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); + return val.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); }, .ComptimeInt => return true, else => unreachable, @@ -26191,7 +26200,7 @@ fn intFitsInType( .aggregate => { assert(ty.zigTypeTag() == .Vector); - for (self.castTag(.aggregate).?.data) |elem, i| { + for (val.castTag(.aggregate).?.data) |elem, i| { if (!(try sema.intFitsInType(block, src, elem, ty.scalarType(), null))) { if (vector_index) |some| some.* = i; return false; diff --git a/src/codegen/spirv/Section.zig b/src/codegen/spirv/Section.zig index 6ed2de92f0..d21c2af8f1 100644 --- a/src/codegen/spirv/Section.zig +++ b/src/codegen/spirv/Section.zig @@ -328,6 +328,8 @@ fn extendedUnionSize(comptime Operand: type, operand: Operand) usize { } test "SPIR-V Section emit() - no operands" { + if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; + var section = Section{}; defer section.deinit(std.testing.allocator); @@ -337,6 +339,8 @@ test "SPIR-V Section emit() - no operands" { } test "SPIR-V Section emit() - simple" { + if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; + var section = Section{}; defer section.deinit(std.testing.allocator); @@ -353,6 +357,8 @@ test "SPIR-V Section emit() - simple" { } test "SPIR-V Section emit() - string" { + if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; + var section = Section{}; defer section.deinit(std.testing.allocator); @@ -378,6 +384,8 @@ test "SPIR-V Section emit() - string" { } test "SPIR-V Section emit()- extended mask" { + if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; + var section = Section{}; defer section.deinit(std.testing.allocator); @@ -402,6 +410,8 @@ test "SPIR-V Section emit()- extended mask" { } test "SPIR-V Section emit() - extended union" { + if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; + var section = Section{}; defer section.deinit(std.testing.allocator); diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 0e7d7c89ee..1b5ddbbf8b 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -809,6 +809,36 @@ pub fn updateDeclExports( if (build_options.skip_non_native and builtin.object_format != .coff) { @panic("Attempted to compile for object format that was disabled by build configuration"); } + + // Even in the case of LLVM, we need to notice certain exported symbols in order to + // detect the default subsystem. + for (exports) |exp| { + const exported_decl = module.declPtr(exp.exported_decl); + if (exported_decl.getFunction() == null) continue; + const winapi_cc = switch (self.base.options.target.cpu.arch) { + .i386 => std.builtin.CallingConvention.Stdcall, + else => std.builtin.CallingConvention.C, + }; + const decl_cc = exported_decl.ty.fnCallingConvention(); + if (decl_cc == .C and mem.eql(u8, exp.options.name, "main") and + self.base.options.link_libc) + { + module.stage1_flags.have_c_main = true; + } else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) { + if (mem.eql(u8, exp.options.name, "WinMain")) { + module.stage1_flags.have_winmain = true; + } else if (mem.eql(u8, exp.options.name, "wWinMain")) { + module.stage1_flags.have_wwinmain = true; + } else if (mem.eql(u8, exp.options.name, "WinMainCRTStartup")) { + module.stage1_flags.have_winmain_crt_startup = true; + } else if (mem.eql(u8, exp.options.name, "wWinMainCRTStartup")) { + module.stage1_flags.have_wwinmain_crt_startup = true; + } else if (mem.eql(u8, exp.options.name, "DllMainCRTStartup")) { + module.stage1_flags.have_dllmain_crt_startup = true; + } + } + } + if (build_options.have_llvm) { if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl_index, exports); } @@ -1114,17 +1144,6 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) ! try argv.append("-dynamicbase"); } - const subsystem_suffix = ss: { - if (self.base.options.major_subsystem_version) |major| { - if (self.base.options.minor_subsystem_version) |minor| { - break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor }); - } else { - break :ss try allocPrint(arena, ",{d}", .{major}); - } - } - break :ss ""; - }; - try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path})); if (self.base.options.implib_emit) |emit| { @@ -1186,57 +1205,71 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) ! } break :blk null; }; + const Mode = enum { uefi, win32 }; const mode: Mode = mode: { - if (resolved_subsystem) |subsystem| switch (subsystem) { - .Console => { - try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{ - subsystem_suffix, - })); - break :mode .win32; - }, - .EfiApplication => { - try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_application{s}", .{ - subsystem_suffix, - })); - break :mode .uefi; - }, - .EfiBootServiceDriver => { - try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_boot_service_driver{s}", .{ - subsystem_suffix, - })); - break :mode .uefi; - }, - .EfiRom => { - try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_rom{s}", .{ - subsystem_suffix, - })); - break :mode .uefi; - }, - .EfiRuntimeDriver => { - try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_runtime_driver{s}", .{ - subsystem_suffix, - })); - break :mode .uefi; - }, - .Native => { - try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{ - subsystem_suffix, - })); - break :mode .win32; - }, - .Posix => { - try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{ - subsystem_suffix, - })); - break :mode .win32; - }, - .Windows => { - try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{ - subsystem_suffix, - })); - break :mode .win32; - }, + if (resolved_subsystem) |subsystem| { + const subsystem_suffix = ss: { + if (self.base.options.major_subsystem_version) |major| { + if (self.base.options.minor_subsystem_version) |minor| { + break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor }); + } else { + break :ss try allocPrint(arena, ",{d}", .{major}); + } + } + break :ss ""; + }; + + switch (subsystem) { + .Console => { + try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{ + subsystem_suffix, + })); + break :mode .win32; + }, + .EfiApplication => { + try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_application{s}", .{ + subsystem_suffix, + })); + break :mode .uefi; + }, + .EfiBootServiceDriver => { + try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_boot_service_driver{s}", .{ + subsystem_suffix, + })); + break :mode .uefi; + }, + .EfiRom => { + try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_rom{s}", .{ + subsystem_suffix, + })); + break :mode .uefi; + }, + .EfiRuntimeDriver => { + try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_runtime_driver{s}", .{ + subsystem_suffix, + })); + break :mode .uefi; + }, + .Native => { + try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{ + subsystem_suffix, + })); + break :mode .win32; + }, + .Posix => { + try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{ + subsystem_suffix, + })); + break :mode .win32; + }, + .Windows => { + try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{ + subsystem_suffix, + })); + break :mode .win32; + }, + } } else if (target.os.tag == .uefi) { break :mode .uefi; } else { |
