Skip to content

Commit 03ed3f5

Browse files
jacobly0kubkon
authored andcommitted
Sema: fix @extern decls
Closes #18550
1 parent 3dddb88 commit 03ed3f5

File tree

3 files changed

+47
-26
lines changed

3 files changed

+47
-26
lines changed

src/Sema.zig

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25675,6 +25675,7 @@ fn zirBuiltinExtern(
2567525675
extended: Zir.Inst.Extended.InstData,
2567625676
) CompileError!Air.Inst.Ref {
2567725677
const mod = sema.mod;
25678+
const ip = &mod.intern_pool;
2567825679
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
2567925680
const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
2568025681
const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
@@ -25714,34 +25715,38 @@ fn zirBuiltinExtern(
2571425715
const new_decl = mod.declPtr(new_decl_index);
2571525716
new_decl.name = options.name;
2571625717

25717-
{
25718-
const new_var = try mod.intern(.{ .variable = .{
25719-
.ty = ptr_info.child,
25720-
.init = .none,
25721-
.decl = sema.owner_decl_index,
25722-
.lib_name = options.library_name,
25723-
.is_extern = true,
25724-
.is_const = ptr_info.flags.is_const,
25725-
.is_threadlocal = options.is_thread_local,
25726-
.is_weak_linkage = options.linkage == .Weak,
25727-
} });
25728-
25729-
new_decl.src_line = sema.owner_decl.src_line;
25730-
// We only access this decl through the decl_ref with the correct type created
25731-
// below, so this type doesn't matter
25732-
new_decl.ty = Type.fromInterned(ptr_info.child);
25733-
new_decl.val = Value.fromInterned(new_var);
25734-
new_decl.alignment = .none;
25735-
new_decl.@"linksection" = .none;
25736-
new_decl.has_tv = true;
25737-
new_decl.analysis = .complete;
25738-
new_decl.generation = mod.generation;
25739-
}
25718+
new_decl.src_line = sema.owner_decl.src_line;
25719+
new_decl.ty = Type.fromInterned(ptr_info.child);
25720+
new_decl.val = Value.fromInterned(
25721+
if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)
25722+
try ip.getExternFunc(sema.gpa, .{
25723+
.ty = ptr_info.child,
25724+
.decl = new_decl_index,
25725+
.lib_name = options.library_name,
25726+
})
25727+
else
25728+
try mod.intern(.{ .variable = .{
25729+
.ty = ptr_info.child,
25730+
.init = .none,
25731+
.decl = new_decl_index,
25732+
.lib_name = options.library_name,
25733+
.is_extern = true,
25734+
.is_const = ptr_info.flags.is_const,
25735+
.is_threadlocal = options.is_thread_local,
25736+
.is_weak_linkage = options.linkage == .Weak,
25737+
} }),
25738+
);
25739+
new_decl.alignment = .none;
25740+
new_decl.@"linksection" = .none;
25741+
new_decl.has_tv = true;
25742+
new_decl.owns_tv = true;
25743+
new_decl.analysis = .complete;
25744+
new_decl.generation = mod.generation;
2574025745

2574125746
try sema.ensureDeclAnalyzed(new_decl_index);
2574225747

2574325748
return Air.internedToRef((try mod.getCoerced(Value.fromInterned((try mod.intern(.{ .ptr = .{
25744-
.ty = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
25749+
.ty = switch (ip.indexToKey(ty.toIntern())) {
2574525750
.ptr_type => ty.toIntern(),
2574625751
.opt_type => |child_type| child_type,
2574725752
else => unreachable,

src/codegen/llvm.zig

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2941,17 +2941,20 @@ pub const Object = struct {
29412941
const target = owner_mod.resolved_target.result;
29422942
const sret = firstParamSRet(fn_info, zcu);
29432943

2944+
const is_extern = decl.isExtern(zcu);
29442945
const function_index = try o.builder.addFunction(
29452946
try o.lowerType(zig_fn_type),
2946-
try o.builder.string(ip.stringToSlice(try decl.getFullyQualifiedName(zcu))),
2947+
try o.builder.string(ip.stringToSlice(if (is_extern)
2948+
decl.name
2949+
else
2950+
try decl.getFullyQualifiedName(zcu))),
29472951
toLlvmAddressSpace(decl.@"addrspace", target),
29482952
);
29492953
gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
29502954

29512955
var attributes: Builder.FunctionAttributes.Wip = .{};
29522956
defer attributes.deinit(&o.builder);
29532957

2954-
const is_extern = decl.isExtern(zcu);
29552958
if (!is_extern) {
29562959
function_index.setLinkage(.internal, &o.builder);
29572960
function_index.setUnnamedAddr(.unnamed_addr, &o.builder);

test/behavior/extern.zig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,16 @@ test "anyopaque extern symbol" {
1212
}
1313

1414
export var a_mystery_symbol: i32 = 1234;
15+
16+
test "function extern symbol" {
17+
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
18+
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
19+
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
20+
21+
const a = @extern(*const fn () callconv(.C) i32, .{ .name = "a_mystery_function" });
22+
try expect(a() == 4567);
23+
}
24+
25+
export fn a_mystery_function() i32 {
26+
return 4567;
27+
}

0 commit comments

Comments
 (0)