| author | |
| committer | |
| log | a4690ecb1fc8a9ac5f7dfccfdf9f67c7a74e1569 |
| tree | c957ba83ecc602392fc4275a53ef9b958b5dbdf1 |
| parent | ee2575724597f214f8f4653f4a4ec1d2a6d97b8b |
Add a note about thread local / dll import being the cause.4 files changed, 22 insertions(+), 7 deletions(-)
src/Sema.zig+11-1| ... | @@ -876,6 +876,7 @@ const InferredAlloc = struct { | ... | @@ -876,6 +876,7 @@ const InferredAlloc = struct { |
| 876 | 876 | ||
| 877 | const NeededComptimeReason = struct { | 877 | const NeededComptimeReason = struct { |
| 878 | needed_comptime_reason: []const u8, | 878 | needed_comptime_reason: []const u8, |
| 879 | value_comptime_reason: ?[]const u8 = null, | ||
| 879 | block_comptime_reason: ?*const Block.ComptimeReason = null, | 880 | block_comptime_reason: ?*const Block.ComptimeReason = null, |
| 880 | }; | 881 | }; |
| 881 | 882 | ||
| ... | @@ -2251,7 +2252,7 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val | ... | @@ -2251,7 +2252,7 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val |
| 2251 | } | 2252 | } |
| 2252 | }; | 2253 | }; |
| 2253 | const val = Value.fromInterned(ip_index); | 2254 | const val = Value.fromInterned(ip_index); |
| 2254 | if (val.isPtrToThreadLocal(pt.zcu)) return null; | 2255 | if (val.isPtrRuntimeValue(pt.zcu)) return null; |
| 2255 | return val; | 2256 | return val; |
| 2256 | } | 2257 | } |
| 2257 | 2258 | ||
| ... | @@ -2277,8 +2278,14 @@ pub fn resolveFinalDeclValue( | ... | @@ -2277,8 +2278,14 @@ pub fn resolveFinalDeclValue( |
| 2277 | const zcu = sema.pt.zcu; | 2278 | const zcu = sema.pt.zcu; |
| 2278 | 2279 | ||
| 2279 | const val = try sema.resolveValueAllowVariables(air_ref) orelse { | 2280 | const val = try sema.resolveValueAllowVariables(air_ref) orelse { |
| 2281 | const value_comptime_reason: ?[]const u8 = if (air_ref.toInterned()) |_| | ||
| 2282 | "thread local and dll imported variables have runtime-known addresses" | ||
| 2283 | else | ||
| 2284 | null; | ||
| 2285 | |||
| 2280 | return sema.failWithNeededComptime(block, src, .{ | 2286 | return sema.failWithNeededComptime(block, src, .{ |
| 2281 | .needed_comptime_reason = "global variable initializer must be comptime-known", | 2287 | .needed_comptime_reason = "global variable initializer must be comptime-known", |
| 2288 | .value_comptime_reason = value_comptime_reason, | ||
| 2282 | }); | 2289 | }); |
| 2283 | }; | 2290 | }; |
| 2284 | if (val.isGenericPoison()) return error.GenericPoison; | 2291 | if (val.isGenericPoison()) return error.GenericPoison; |
| ... | @@ -2296,6 +2303,9 @@ fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc, reason: N | ... | @@ -2296,6 +2303,9 @@ fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc, reason: N |
| 2296 | const msg = try sema.errMsg(src, "unable to resolve comptime value", .{}); | 2303 | const msg = try sema.errMsg(src, "unable to resolve comptime value", .{}); |
| 2297 | errdefer msg.destroy(sema.gpa); | 2304 | errdefer msg.destroy(sema.gpa); |
| 2298 | try sema.errNote(src, msg, "{s}", .{reason.needed_comptime_reason}); | 2305 | try sema.errNote(src, msg, "{s}", .{reason.needed_comptime_reason}); |
| 2306 | if (reason.value_comptime_reason) |value_comptime_reason| { | ||
| 2307 | try sema.errNote(src, msg, "{s}", .{value_comptime_reason}); | ||
| 2308 | } | ||
| 2299 | 2309 | ||
| 2300 | if (reason.block_comptime_reason) |block_comptime_reason| { | 2310 | if (reason.block_comptime_reason) |block_comptime_reason| { |
| 2301 | try block_comptime_reason.explain(sema, msg); | 2311 | try block_comptime_reason.explain(sema, msg); |
src/Value.zig+2-2| ... | @@ -1340,11 +1340,11 @@ pub fn isLazySize(val: Value, zcu: *Zcu) bool { | ... | @@ -1340,11 +1340,11 @@ pub fn isLazySize(val: Value, zcu: *Zcu) bool { |
| 1340 | }; | 1340 | }; |
| 1341 | } | 1341 | } |
| 1342 | 1342 | ||
| 1343 | pub fn isPtrToThreadLocal(val: Value, zcu: *Zcu) bool { | 1343 | pub fn isPtrRuntimeValue(val: Value, zcu: *Zcu) bool { |
| 1344 | const ip = &zcu.intern_pool; | 1344 | const ip = &zcu.intern_pool; |
| 1345 | const nav = ip.getBackingNav(val.toIntern()).unwrap() orelse return false; | 1345 | const nav = ip.getBackingNav(val.toIntern()).unwrap() orelse return false; |
| 1346 | return switch (ip.indexToKey(ip.getNav(nav).status.resolved.val)) { | 1346 | return switch (ip.indexToKey(ip.getNav(nav).status.resolved.val)) { |
| 1347 | .@"extern" => |e| e.is_threadlocal, | 1347 | .@"extern" => |e| e.is_threadlocal or e.is_dll_import, |
| 1348 | .variable => |v| v.is_threadlocal, | 1348 | .variable => |v| v.is_threadlocal, |
| 1349 | else => false, | 1349 | else => false, |
| 1350 | }; | 1350 | }; |
src/codegen/llvm.zig+5-4| ... | @@ -3237,10 +3237,10 @@ pub const Object = struct { | ... | @@ -3237,10 +3237,10 @@ pub const Object = struct { |
| 3237 | const ip = &zcu.intern_pool; | 3237 | const ip = &zcu.intern_pool; |
| 3238 | const nav = ip.getNav(nav_index); | 3238 | const nav = ip.getNav(nav_index); |
| 3239 | const resolved = nav.status.resolved; | 3239 | const resolved = nav.status.resolved; |
| 3240 | const is_extern, const is_threadlocal, const is_weak_linkage = switch (ip.indexToKey(resolved.val)) { | 3240 | const is_extern, const is_threadlocal, const is_weak_linkage, const is_dll_import = switch (ip.indexToKey(resolved.val)) { |
| 3241 | .variable => |variable| .{ false, variable.is_threadlocal, variable.is_weak_linkage }, | 3241 | .variable => |variable| .{ false, variable.is_threadlocal, variable.is_weak_linkage, false }, |
| 3242 | .@"extern" => |@"extern"| .{ true, @"extern".is_threadlocal, @"extern".is_weak_linkage }, | 3242 | .@"extern" => |@"extern"| .{ true, @"extern".is_threadlocal, @"extern".is_weak_linkage, @"extern".is_dll_import }, |
| 3243 | else => .{ false, false, false }, | 3243 | else => .{ false, false, false, false }, |
| 3244 | }; | 3244 | }; |
| 3245 | 3245 | ||
| 3246 | const variable_index = try o.builder.addVariable( | 3246 | const variable_index = try o.builder.addVariable( |
| ... | @@ -3257,6 +3257,7 @@ pub const Object = struct { | ... | @@ -3257,6 +3257,7 @@ pub const Object = struct { |
| 3257 | if (is_threadlocal and !zcu.navFileScope(nav_index).mod.single_threaded) | 3257 | if (is_threadlocal and !zcu.navFileScope(nav_index).mod.single_threaded) |
| 3258 | variable_index.setThreadLocal(.generaldynamic, &o.builder); | 3258 | variable_index.setThreadLocal(.generaldynamic, &o.builder); |
| 3259 | if (is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder); | 3259 | if (is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder); |
| 3260 | if (is_dll_import) variable_index.setDllStorageClass(.dllimport, &o.builder); | ||
| 3260 | } else { | 3261 | } else { |
| 3261 | variable_index.setLinkage(.internal, &o.builder); | 3262 | variable_index.setLinkage(.internal, &o.builder); |
| 3262 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); | 3263 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
src/codegen/llvm/Builder.zig+4| ... | @@ -2528,6 +2528,10 @@ pub const Variable = struct { | ... | @@ -2528,6 +2528,10 @@ pub const Variable = struct { |
| 2528 | return self.ptrConst(builder).global.setLinkage(linkage, builder); | 2528 | return self.ptrConst(builder).global.setLinkage(linkage, builder); |
| 2529 | } | 2529 | } |
| 2530 | 2530 | ||
| 2531 | pub fn setDllStorageClass(self: Index, class: DllStorageClass, builder: *Builder) void { | ||
| 2532 | return self.ptrConst(builder).global.setDllStorageClass(class, builder); | ||
| 2533 | } | ||
| 2534 | |||
| 2531 | pub fn setUnnamedAddr(self: Index, unnamed_addr: UnnamedAddr, builder: *Builder) void { | 2535 | pub fn setUnnamedAddr(self: Index, unnamed_addr: UnnamedAddr, builder: *Builder) void { |
| 2532 | return self.ptrConst(builder).global.setUnnamedAddr(unnamed_addr, builder); | 2536 | return self.ptrConst(builder).global.setUnnamedAddr(unnamed_addr, builder); |
| 2533 | } | 2537 | } |