authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2024-10-20 16:30:12-04:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2024-10-22 12:41:35-04:00
loga4690ecb1fc8a9ac5f7dfccfdf9f67c7a74e1569
treec957ba83ecc602392fc4275a53ef9b958b5dbdf1
parentee2575724597f214f8f4653f4a4ec1d2a6d97b8b

Cause a compilation error to occur if using @extern with is_dll_import in a comptime scope.

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 {
876876
877const NeededComptimeReason = struct {877const 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};
881882
...@@ -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}
22572258
...@@ -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;
22782279
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 }
22992309
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}
13421342
1343pub fn isPtrToThreadLocal(val: Value, zcu: *Zcu) bool {1343pub 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 };
32453245
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 }
25302530
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 }