diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 0eecbb4f87..01da7ba9a2 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3256,7 +3256,12 @@ pub const Object = struct { 128 => .fp128, else => unreachable, }, - .anyopaque_type => unreachable, + .anyopaque_type => { + // This is unreachable except when used as the type for an extern global. + // For example: `@extern(*anyopaque, .{ .name = "foo"})` should produce + // @foo = external global i8 + return .i8; + }, .bool_type => .i1, .void_type => .void, .type_type => unreachable, diff --git a/test/behavior.zig b/test/behavior.zig index d890a3c25f..b8af6b544e 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -32,6 +32,7 @@ test { _ = @import("behavior/eval.zig"); _ = @import("behavior/export_builtin.zig"); _ = @import("behavior/export_self_referential_type_info.zig"); + _ = @import("behavior/extern.zig"); _ = @import("behavior/field_parent_ptr.zig"); _ = @import("behavior/floatop.zig"); _ = @import("behavior/fn.zig"); diff --git a/test/behavior/extern.zig b/test/behavior/extern.zig new file mode 100644 index 0000000000..87a93624d0 --- /dev/null +++ b/test/behavior/extern.zig @@ -0,0 +1,14 @@ +const builtin = @import("builtin"); +const std = @import("std"); +const expect = std.testing.expect; + +test "anyopaque extern symbol" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; + + const a = @extern(*anyopaque, .{ .name = "a_mystery_symbol" }); + const b: *i32 = @alignCast(@ptrCast(a)); + try expect(b.* == 1234); +} + +export var a_mystery_symbol: i32 = 1234;