| 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 | 876 | |
| 877 | 877 | const NeededComptimeReason = struct { |
| 878 | 878 | needed_comptime_reason: []const u8, |
| 879 | value_comptime_reason: ?[]const u8 = null, | |
| 879 | 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 | 2252 | } |
| 2252 | 2253 | }; |
| 2253 | 2254 | const val = Value.fromInterned(ip_index); |
| 2254 | if (val.isPtrToThreadLocal(pt.zcu)) return null; | |
| 2255 | if (val.isPtrRuntimeValue(pt.zcu)) return null; | |
| 2255 | 2256 | return val; |
| 2256 | 2257 | } |
| 2257 | 2258 | |
| ... | ... | @@ -2277,8 +2278,14 @@ pub fn resolveFinalDeclValue( |
| 2277 | 2278 | const zcu = sema.pt.zcu; |
| 2278 | 2279 | |
| 2279 | 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 | 2286 | return sema.failWithNeededComptime(block, src, .{ |
| 2281 | 2287 | .needed_comptime_reason = "global variable initializer must be comptime-known", |
| 2288 | .value_comptime_reason = value_comptime_reason, | |
| 2282 | 2289 | }); |
| 2283 | 2290 | }; |
| 2284 | 2291 | if (val.isGenericPoison()) return error.GenericPoison; |
| ... | ... | @@ -2296,6 +2303,9 @@ fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc, reason: N |
| 2296 | 2303 | const msg = try sema.errMsg(src, "unable to resolve comptime value", .{}); |
| 2297 | 2304 | errdefer msg.destroy(sema.gpa); |
| 2298 | 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 | 2310 | if (reason.block_comptime_reason) |block_comptime_reason| { |
| 2301 | 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 | 1340 | }; |
| 1341 | 1341 | } |
| 1342 | 1342 | |
| 1343 | pub fn isPtrToThreadLocal(val: Value, zcu: *Zcu) bool { | |
| 1343 | pub fn isPtrRuntimeValue(val: Value, zcu: *Zcu) bool { | |
| 1344 | 1344 | const ip = &zcu.intern_pool; |
| 1345 | 1345 | const nav = ip.getBackingNav(val.toIntern()).unwrap() orelse return false; |
| 1346 | 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 | 1348 | .variable => |v| v.is_threadlocal, |
| 1349 | 1349 | else => false, |
| 1350 | 1350 | }; |
src/codegen/llvm.zig+5-4| ... | ... | @@ -3237,10 +3237,10 @@ pub const Object = struct { |
| 3237 | 3237 | const ip = &zcu.intern_pool; |
| 3238 | 3238 | const nav = ip.getNav(nav_index); |
| 3239 | 3239 | const resolved = nav.status.resolved; |
| 3240 | const is_extern, const is_threadlocal, const is_weak_linkage = switch (ip.indexToKey(resolved.val)) { | |
| 3241 | .variable => |variable| .{ false, variable.is_threadlocal, variable.is_weak_linkage }, | |
| 3242 | .@"extern" => |@"extern"| .{ true, @"extern".is_threadlocal, @"extern".is_weak_linkage }, | |
| 3243 | else => .{ false, false, false }, | |
| 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, false }, | |
| 3242 | .@"extern" => |@"extern"| .{ true, @"extern".is_threadlocal, @"extern".is_weak_linkage, @"extern".is_dll_import }, | |
| 3243 | else => .{ false, false, false, false }, | |
| 3244 | 3244 | }; |
| 3245 | 3245 | |
| 3246 | 3246 | const variable_index = try o.builder.addVariable( |
| ... | ... | @@ -3257,6 +3257,7 @@ pub const Object = struct { |
| 3257 | 3257 | if (is_threadlocal and !zcu.navFileScope(nav_index).mod.single_threaded) |
| 3258 | 3258 | variable_index.setThreadLocal(.generaldynamic, &o.builder); |
| 3259 | 3259 | if (is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder); |
| 3260 | if (is_dll_import) variable_index.setDllStorageClass(.dllimport, &o.builder); | |
| 3260 | 3261 | } else { |
| 3261 | 3262 | variable_index.setLinkage(.internal, &o.builder); |
| 3262 | 3263 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
src/codegen/llvm/Builder.zig+4| ... | ... | @@ -2528,6 +2528,10 @@ pub const Variable = struct { |
| 2528 | 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 | 2535 | pub fn setUnnamedAddr(self: Index, unnamed_addr: UnnamedAddr, builder: *Builder) void { |
| 2532 | 2536 | return self.ptrConst(builder).global.setUnnamedAddr(unnamed_addr, builder); |
| 2533 | 2537 | } |