diff --git a/src/InternPool.zig b/src/InternPool.zig index e396b85059..40e4521d4b 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -2676,8 +2676,8 @@ pub const Key = union(enum) { asBytes(&e.ty) ++ asBytes(&e.lib_name) ++ asBytes(&e.is_const) ++ asBytes(&e.is_threadlocal) ++ asBytes(&e.is_weak_linkage) ++ asBytes(&e.alignment) ++ - asBytes(&e.is_dll_import) ++ asBytes(&e.alignment) ++ - asBytes(&e.@"addrspace") ++ asBytes(&e.zir_index)), + asBytes(&e.is_dll_import) ++ asBytes(&e.@"addrspace") ++ + asBytes(&e.zir_index)), }; } diff --git a/test/cases/compile_errors/builtin_extern_in_comptime_scope.zig b/test/cases/compile_errors/builtin_extern_in_comptime_scope.zig new file mode 100644 index 0000000000..4a85ee8aab --- /dev/null +++ b/test/cases/compile_errors/builtin_extern_in_comptime_scope.zig @@ -0,0 +1,18 @@ +const foo_tl = @extern(*i32, .{ .name = "foo", .is_thread_local = true }); +const foo_dll = @extern(*i32, .{ .name = "foo", .is_dll_import = true }); +pub export fn entry() void { + _ = foo_tl; +} +pub export fn entry2() void { + _ = foo_dll; +} +// error +// backend=stage2 +// target=native +// +// :1:16: error: unable to resolve comptime value +// :1:16: note: global variable initializer must be comptime-known +// :1:16: note: thread local and dll imported variables have runtime-known addresses +// :2:17: error: unable to resolve comptime value +// :2:17: note: global variable initializer must be comptime-known +// :2:17: note: thread local and dll imported variables have runtime-known addresses diff --git a/test/standalone/extern/build.zig b/test/standalone/extern/build.zig index a378735b66..ff8701bf40 100644 --- a/test/standalone/extern/build.zig +++ b/test/standalone/extern/build.zig @@ -1,6 +1,9 @@ const std = @import("std"); pub fn build(b: *std.Build) void { + const test_step = b.step("test", "Test it"); + b.default_step = test_step; + const optimize: std.builtin.OptimizeMode = .Debug; const obj = b.addObject(.{ @@ -9,12 +12,20 @@ pub fn build(b: *std.Build) void { .target = b.graph.host, .optimize = optimize, }); - const main = b.addTest(.{ + const shared = b.addSharedLibrary(.{ + .name = "shared", + .target = b.graph.host, + .optimize = optimize, + .link_libc = true, + }); + if (b.graph.host.result.abi == .msvc) shared.defineCMacro("API", "__declspec(dllexport)"); + shared.addCSourceFile(.{ .file = b.path("shared.c"), .flags = &.{} }); + const test_exe = b.addTest(.{ .root_source_file = b.path("main.zig"), .optimize = optimize, }); - main.addObject(obj); + test_exe.addObject(obj); + test_exe.linkLibrary(shared); - const test_step = b.step("test", "Test it"); - test_step.dependOn(&main.step); + test_step.dependOn(&b.addRunArtifact(test_exe).step); } diff --git a/test/standalone/extern/main.zig b/test/standalone/extern/main.zig index 3f5168f841..d27c40bd80 100644 --- a/test/standalone/extern/main.zig +++ b/test/standalone/extern/main.zig @@ -1,4 +1,5 @@ const assert = @import("std").debug.assert; +const testing = @import("std").testing; const updateHidden = @extern(*const fn (u32) callconv(.C) void, .{ .name = "updateHidden" }); const getHidden = @extern(*const fn () callconv(.C) u32, .{ .name = "getHidden" }); @@ -8,14 +9,18 @@ const T = extern struct { x: u32 }; test { const mut_val_ptr = @extern(*f64, .{ .name = "mut_val" }); const const_val_ptr = @extern(*const T, .{ .name = "const_val" }); + const shared_val_ptr = @extern(*c_int, .{ .name = "shared_val", .is_dll_import = true }); assert(getHidden() == 0); updateHidden(123); assert(getHidden() == 123); - assert(mut_val_ptr.* == 1.23); mut_val_ptr.* = 10.0; assert(mut_val_ptr.* == 10.0); assert(const_val_ptr.x == 42); + + assert(shared_val_ptr.* == 1234); + shared_val_ptr.* = 1235; + assert(shared_val_ptr.* == 1235); } diff --git a/test/standalone/extern/shared.c b/test/standalone/extern/shared.c new file mode 100644 index 0000000000..845963c848 --- /dev/null +++ b/test/standalone/extern/shared.c @@ -0,0 +1,5 @@ +#ifndef API +#define API +#endif + +API int shared_val = 1234;