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.
This commit is contained in:
12
src/Sema.zig
12
src/Sema.zig
@@ -876,6 +876,7 @@ const InferredAlloc = struct {
|
||||
|
||||
const NeededComptimeReason = struct {
|
||||
needed_comptime_reason: []const u8,
|
||||
value_comptime_reason: ?[]const u8 = null,
|
||||
block_comptime_reason: ?*const Block.ComptimeReason = null,
|
||||
};
|
||||
|
||||
@@ -2251,7 +2252,7 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val
|
||||
}
|
||||
};
|
||||
const val = Value.fromInterned(ip_index);
|
||||
if (val.isPtrToThreadLocal(pt.zcu)) return null;
|
||||
if (val.isPtrRuntimeValue(pt.zcu)) return null;
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -2277,8 +2278,14 @@ pub fn resolveFinalDeclValue(
|
||||
const zcu = sema.pt.zcu;
|
||||
|
||||
const val = try sema.resolveValueAllowVariables(air_ref) orelse {
|
||||
const value_comptime_reason: ?[]const u8 = if (air_ref.toInterned()) |_|
|
||||
"thread local and dll imported variables have runtime-known addresses"
|
||||
else
|
||||
null;
|
||||
|
||||
return sema.failWithNeededComptime(block, src, .{
|
||||
.needed_comptime_reason = "global variable initializer must be comptime-known",
|
||||
.value_comptime_reason = value_comptime_reason,
|
||||
});
|
||||
};
|
||||
if (val.isGenericPoison()) return error.GenericPoison;
|
||||
@@ -2296,6 +2303,9 @@ fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc, reason: N
|
||||
const msg = try sema.errMsg(src, "unable to resolve comptime value", .{});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
try sema.errNote(src, msg, "{s}", .{reason.needed_comptime_reason});
|
||||
if (reason.value_comptime_reason) |value_comptime_reason| {
|
||||
try sema.errNote(src, msg, "{s}", .{value_comptime_reason});
|
||||
}
|
||||
|
||||
if (reason.block_comptime_reason) |block_comptime_reason| {
|
||||
try block_comptime_reason.explain(sema, msg);
|
||||
|
||||
@@ -1340,11 +1340,11 @@ pub fn isLazySize(val: Value, zcu: *Zcu) bool {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isPtrToThreadLocal(val: Value, zcu: *Zcu) bool {
|
||||
pub fn isPtrRuntimeValue(val: Value, zcu: *Zcu) bool {
|
||||
const ip = &zcu.intern_pool;
|
||||
const nav = ip.getBackingNav(val.toIntern()).unwrap() orelse return false;
|
||||
return switch (ip.indexToKey(ip.getNav(nav).status.resolved.val)) {
|
||||
.@"extern" => |e| e.is_threadlocal,
|
||||
.@"extern" => |e| e.is_threadlocal or e.is_dll_import,
|
||||
.variable => |v| v.is_threadlocal,
|
||||
else => false,
|
||||
};
|
||||
|
||||
@@ -3237,10 +3237,10 @@ pub const Object = struct {
|
||||
const ip = &zcu.intern_pool;
|
||||
const nav = ip.getNav(nav_index);
|
||||
const resolved = nav.status.resolved;
|
||||
const is_extern, const is_threadlocal, const is_weak_linkage = switch (ip.indexToKey(resolved.val)) {
|
||||
.variable => |variable| .{ false, variable.is_threadlocal, variable.is_weak_linkage },
|
||||
.@"extern" => |@"extern"| .{ true, @"extern".is_threadlocal, @"extern".is_weak_linkage },
|
||||
else => .{ false, false, false },
|
||||
const is_extern, const is_threadlocal, const is_weak_linkage, const is_dll_import = switch (ip.indexToKey(resolved.val)) {
|
||||
.variable => |variable| .{ false, variable.is_threadlocal, variable.is_weak_linkage, false },
|
||||
.@"extern" => |@"extern"| .{ true, @"extern".is_threadlocal, @"extern".is_weak_linkage, @"extern".is_dll_import },
|
||||
else => .{ false, false, false, false },
|
||||
};
|
||||
|
||||
const variable_index = try o.builder.addVariable(
|
||||
@@ -3257,6 +3257,7 @@ pub const Object = struct {
|
||||
if (is_threadlocal and !zcu.navFileScope(nav_index).mod.single_threaded)
|
||||
variable_index.setThreadLocal(.generaldynamic, &o.builder);
|
||||
if (is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder);
|
||||
if (is_dll_import) variable_index.setDllStorageClass(.dllimport, &o.builder);
|
||||
} else {
|
||||
variable_index.setLinkage(.internal, &o.builder);
|
||||
variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
|
||||
|
||||
@@ -2528,6 +2528,10 @@ pub const Variable = struct {
|
||||
return self.ptrConst(builder).global.setLinkage(linkage, builder);
|
||||
}
|
||||
|
||||
pub fn setDllStorageClass(self: Index, class: DllStorageClass, builder: *Builder) void {
|
||||
return self.ptrConst(builder).global.setDllStorageClass(class, builder);
|
||||
}
|
||||
|
||||
pub fn setUnnamedAddr(self: Index, unnamed_addr: UnnamedAddr, builder: *Builder) void {
|
||||
return self.ptrConst(builder).global.setUnnamedAddr(unnamed_addr, builder);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user