Commit 7edd69d8aa

kcbanner <kcbanner@gmail.com>
2024-10-21 00:42:38
tests: add tests for is_dll_import externs
- tests/standalone/extern wasn't running its test step - add compile error tests for thread local / dll import @extern in a comptime scope
1 parent b87fa93
Changed files (5)
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)),
         };
     }
 
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
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);
 }
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);
 }
test/standalone/extern/shared.c
@@ -0,0 +1,5 @@
+#ifndef API
+#define API
+#endif
+
+API int shared_val = 1234;