diff --git a/src/InternPool.zig b/src/InternPool.zig index 0aa664d611..5f108e3224 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -2257,6 +2257,7 @@ pub const Key = union(enum) { /// The `Nav` corresponding to this extern symbol. /// This is ignored by hashing and equality. owner_nav: Nav.Index, + source: Tag.Extern.Flags.Source, }; pub const Func = struct { @@ -2859,7 +2860,7 @@ pub const Key = union(enum) { asBytes(&e.is_threadlocal) ++ asBytes(&e.is_dll_import) ++ asBytes(&e.relocation) ++ asBytes(&e.is_const) ++ asBytes(&e.alignment) ++ asBytes(&e.@"addrspace") ++ - asBytes(&e.zir_index)), + asBytes(&e.zir_index) ++ &[1]u8{@intFromEnum(e.source)}), }; } @@ -2958,7 +2959,8 @@ pub const Key = union(enum) { a_info.is_const == b_info.is_const and a_info.alignment == b_info.alignment and a_info.@"addrspace" == b_info.@"addrspace" and - a_info.zir_index == b_info.zir_index; + a_info.zir_index == b_info.zir_index and + a_info.source == b_info.source; }, .func => |a_info| { const b_info = b.func; @@ -5967,7 +5969,10 @@ pub const Tag = enum(u8) { is_threadlocal: bool, is_dll_import: bool, relocation: std.builtin.ExternOptions.Relocation, - _: u25 = 0, + source: Source, + _: u24 = 0, + + pub const Source = enum(u1) { builtin, syntax }; }; }; @@ -7320,6 +7325,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { .@"addrspace" = nav.status.fully_resolved.@"addrspace", .zir_index = extra.zir_index, .owner_nav = extra.owner_nav, + .source = extra.flags.source, } }; }, .func_instance => .{ .func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) }, @@ -9212,6 +9218,7 @@ pub fn getExtern( .is_threadlocal = key.is_threadlocal, .is_dll_import = key.is_dll_import, .relocation = key.relocation, + .source = key.source, }, .zir_index = key.zir_index, .owner_nav = owner_nav, diff --git a/src/Sema.zig b/src/Sema.zig index 34e862dbbb..4d05441a83 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -25768,6 +25768,7 @@ fn zirBuiltinExtern( }, }, .owner_nav = undefined, // ignored by `getExtern` + .source = .builtin, }); const uncasted_ptr = try sema.analyzeNavRef(block, src, ip.indexToKey(extern_val).@"extern".owner_nav); diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 6d2da7afa4..3c2bb27dab 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -1249,6 +1249,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr .@"addrspace" = modifiers.@"addrspace", .zir_index = old_nav.analysis.?.zir_index, // `declaration` instruction .owner_nav = undefined, // ignored by `getExtern` + .source = .syntax, })); }, }; @@ -3435,6 +3436,7 @@ pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!V .@"addrspace" = e.@"addrspace", .zir_index = e.zir_index, .owner_nav = undefined, // ignored by `getExtern`. + .source = e.source, }); return Value.fromInterned(coerced); }, diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 70b4eab1ae..f4af5f4148 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -1720,7 +1720,7 @@ pub const WipNav = struct { std.leb.writeUnsignedFixed( block_bytes, wip_nav.debug_info.written()[block.abbrev_code..][0..block_bytes], - try wip_nav.dwarf.refAbbrevCode(.empty_block), + @intCast(try wip_nav.dwarf.refAbbrevCode(.empty_block)), ); std.mem.writeInt(u32, wip_nav.debug_info.written()[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian); wip_nav.any_children = true; @@ -1782,7 +1782,7 @@ pub const WipNav = struct { std.leb.writeUnsignedFixed( inlined_func_bytes, wip_nav.debug_info.written()[block.abbrev_code..][0..inlined_func_bytes], - try wip_nav.dwarf.refAbbrevCode(.empty_inlined_func), + @intCast(try wip_nav.dwarf.refAbbrevCode(.empty_inlined_func)), ); std.mem.writeInt(u32, wip_nav.debug_info.written()[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian); try wip_nav.setInlineFunc(func); @@ -2077,7 +2077,11 @@ pub const WipNav = struct { const ty = value.typeOf(zcu); if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null); if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType()); - if (ip.isFunctionType(ty.toIntern()) and !value.isUndef(zcu)) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav); + if (ip.isFunctionType(ty.toIntern()) and !value.isUndef(zcu)) return wip_nav.getNavEntry(switch (ip.indexToKey(value.toIntern())) { + else => unreachable, + .func => |func| func.owner_nav, + .@"extern" => |@"extern"| @"extern".owner_nav, + }); const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern()); const unit: Unit.Index = .main; if (gop.found_existing) return .{ unit, gop.value_ptr.* }; @@ -2250,6 +2254,8 @@ pub const WipNav = struct { .decl_func, .decl_nullary_func_generic, .decl_func_generic, + .decl_extern_nullary_func, + .decl_extern_func, => false, .generic_decl_var, .generic_decl_const, @@ -2585,7 +2591,7 @@ pub fn initWipNav( pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, sym_index: u32, -) error{ OutOfMemory, CodegenFail }!?WipNav { +) error{ OutOfMemory, CodegenFail }!WipNav { return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) { error.OutOfMemory => error.OutOfMemory, else => |e| pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}), @@ -2597,7 +2603,7 @@ fn initWipNavInner( pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, sym_index: u32, -) !?WipNav { +) !WipNav { const zcu = pt.zcu; const ip = &zcu.intern_pool; @@ -2613,15 +2619,6 @@ fn initWipNavInner( nav.fqn.fmt(ip), }); - const nav_val = zcu.navValue(nav_index); - const nav_key = ip.indexToKey(nav_val.toIntern()); - switch (nav_key) { - // Ignore @extern - .@"extern" => |@"extern"| if (decl.linkage != .@"extern" or - !@"extern".name.eqlSlice(file.zir.?.nullTerminatedString(decl.name), ip)) return null, - else => {}, - } - const mod = file.mod.?; const unit = try dwarf.getUnit(mod); const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); @@ -2654,44 +2651,63 @@ fn initWipNavInner( }; errdefer wip_nav.deinit(); - switch (nav_key) { - else => { - const diw = &wip_nav.debug_info.writer; - try wip_nav.declCommon(.{ - .decl = .decl_var, - .generic_decl = .generic_decl_var, - .decl_instance = .decl_instance_var, - }, &nav, inst_info.file, &decl); - try wip_nav.strp(nav.fqn.toSlice(ip)); - const ty: Type = nav_val.typeOf(zcu); - const addr: Loc = .{ .addr_reloc = sym_index }; - const loc: Loc = if (decl.is_threadlocal) loc: { - const target = zcu.comp.root_mod.resolved_target.result; - break :loc switch (target.cpu.arch) { - .x86_64 => .{ .form_tls_address = &addr }, - else => .empty, + const nav_val = zcu.navValue(nav_index); + nav_val: switch (ip.indexToKey(nav_val.toIntern())) { + .@"extern" => |@"extern"| switch (@"extern".source) { + .builtin => { + const maybe_func_type = switch (ip.indexToKey(@"extern".ty)) { + .func_type => |func_type| func_type, + else => null, }; - } else addr; - switch (decl.kind) { - .unnamed_test, .@"test", .decltest, .@"comptime" => unreachable, - .@"const" => { - const const_ty_reloc_index = try wip_nav.refForward(); - try wip_nav.infoExprLoc(loc); - try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse - ty.abiAlignment(zcu).toByteUnits().?); - try diw.writeByte(@intFromBool(decl.linkage != .normal)); - wip_nav.finishForward(const_ty_reloc_index); - try wip_nav.abbrevCode(.is_const); - try wip_nav.refType(ty); + const diw = &wip_nav.debug_info.writer; + try wip_nav.abbrevCode(if (maybe_func_type) |func_type| + if (func_type.param_types.len > 0 or func_type.is_var_args) .builtin_extern_func else .builtin_extern_nullary_func + else + .builtin_extern_var); + try wip_nav.refType(.fromInterned(zcu.fileRootType(inst_info.file))); + try wip_nav.strp(@"extern".name.toSlice(ip)); + try wip_nav.refType(.fromInterned(if (maybe_func_type) |func_type| func_type.return_type else @"extern".ty)); + if (maybe_func_type) |func_type| { + try wip_nav.infoAddrSym(sym_index, 0); + try diw.writeByte(@intFromBool(ip.isNoReturn(func_type.return_type))); + if (func_type.param_types.len > 0 or func_type.is_var_args) { + for (func_type.param_types.get(ip)) |param_type| { + try wip_nav.abbrevCode(.extern_param); + try wip_nav.refType(.fromInterned(param_type)); + } + if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args); + try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); + } + } else try wip_nav.infoExprLoc(.{ .addr_reloc = sym_index }); + }, + .syntax => switch (ip.isFunctionType(@"extern".ty)) { + false => continue :nav_val .{ .variable = undefined }, + true => { + const func_type = ip.indexToKey(@"extern".ty).func_type; + const diw = &wip_nav.debug_info.writer; + try wip_nav.declCommon(if (func_type.param_types.len > 0 or func_type.is_var_args) .{ + .decl = .decl_extern_func, + .generic_decl = .generic_decl_func, + .decl_instance = .decl_instance_extern_func, + } else .{ + .decl = .decl_extern_nullary_func, + .generic_decl = .generic_decl_func, + .decl_instance = .decl_instance_extern_nullary_func, + }, &nav, inst_info.file, &decl); + try wip_nav.strp(@"extern".name.toSlice(ip)); + try wip_nav.refType(.fromInterned(func_type.return_type)); + try wip_nav.infoAddrSym(sym_index, 0); + try diw.writeByte(@intFromBool(ip.isNoReturn(func_type.return_type))); + if (func_type.param_types.len > 0 or func_type.is_var_args) { + for (func_type.param_types.get(ip)) |param_type| { + try wip_nav.abbrevCode(.extern_param); + try wip_nav.refType(.fromInterned(param_type)); + } + if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args); + try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); + } }, - .@"var" => { - try wip_nav.refType(ty); - try wip_nav.infoExprLoc(loc); - try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse - ty.abiAlignment(zcu).toByteUnits().?); - try diw.writeByte(@intFromBool(decl.linkage != .normal)); - }, - } + }, }, .func => |func| if (func.owner_nav != nav_index) { try wip_nav.declCommon(.{ @@ -2752,7 +2768,10 @@ fn initWipNavInner( .generic_decl = .generic_decl_func, .decl_instance = .decl_instance_func, }, &nav, inst_info.file, &decl); - try wip_nav.strp(nav.fqn.toSlice(ip)); + try wip_nav.strp(switch (decl.linkage) { + .normal => nav.fqn, + .@"extern", .@"export" => nav.name, + }.toSlice(ip)); try wip_nav.refType(.fromInterned(func_type.return_type)); try wip_nav.infoAddrSym(sym_index, 0); wip_nav.func_high_pc = @intCast(diw.end); @@ -2763,7 +2782,7 @@ fn initWipNavInner( else => |a| a.maxStrict(target_info.minFunctionAlignment(target)), }.toByteUnits().?); try diw.writeByte(@intFromBool(decl.linkage != .normal)); - try diw.writeByte(@intFromBool(func_type.return_type == .noreturn_type)); + try diw.writeByte(@intFromBool(ip.isNoReturn(func_type.return_type))); const dlw = &wip_nav.debug_line.writer; try dlw.writeByte(DW.LNS.extended_op); @@ -2801,6 +2820,47 @@ fn initWipNavInner( try wip_nav.advancePCAndLine(@intCast(decl.src_line + func.lbrace_line), 0); } }, + else => { + const diw = &wip_nav.debug_info.writer; + try wip_nav.declCommon(.{ + .decl = .decl_var, + .generic_decl = .generic_decl_var, + .decl_instance = .decl_instance_var, + }, &nav, inst_info.file, &decl); + try wip_nav.strp(switch (decl.linkage) { + .normal => nav.fqn, + .@"extern", .@"export" => nav.name, + }.toSlice(ip)); + const ty: Type = nav_val.typeOf(zcu); + const addr: Loc = .{ .addr_reloc = sym_index }; + const loc: Loc = if (decl.is_threadlocal) loc: { + const target = zcu.comp.root_mod.resolved_target.result; + break :loc switch (target.cpu.arch) { + .x86_64 => .{ .form_tls_address = &addr }, + else => .empty, + }; + } else addr; + switch (decl.kind) { + .unnamed_test, .@"test", .decltest, .@"comptime" => unreachable, + .@"const" => { + const const_ty_reloc_index = try wip_nav.refForward(); + try wip_nav.infoExprLoc(loc); + try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse + ty.abiAlignment(zcu).toByteUnits().?); + try diw.writeByte(@intFromBool(decl.linkage != .normal)); + wip_nav.finishForward(const_ty_reloc_index); + try wip_nav.abbrevCode(.is_const); + try wip_nav.refType(ty); + }, + .@"var" => { + try wip_nav.refType(ty); + try wip_nav.infoExprLoc(loc); + try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse + ty.abiAlignment(zcu).toByteUnits().?); + try diw.writeByte(@intFromBool(decl.linkage != .normal)); + }, + } + }, } return wip_nav; } @@ -2891,11 +2951,11 @@ fn finishWipNavFuncWriterError( std.leb.writeUnsignedFixed( AbbrevCode.decl_bytes, abbrev_code_buf, - try dwarf.refAbbrevCode(switch (abbrev_code) { + @intCast(try dwarf.refAbbrevCode(switch (abbrev_code) { else => unreachable, .decl_func => .decl_nullary_func, .decl_instance_func => .decl_instance_nullary_func, - }), + })), ); } } @@ -3357,7 +3417,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo .generic_decl = .generic_decl_var, .decl_instance = .decl_instance_var, }, &nav, inst_info.file, &decl); - try wip_nav.strp(nav.fqn.toSlice(ip)); + try wip_nav.strp(switch (decl.linkage) { + .normal => nav.fqn, + .@"extern", .@"export" => nav.name, + }.toSlice(ip)); const nav_ty = nav_val.typeOf(zcu); try wip_nav.refType(nav_ty); try wip_nav.blockValue(nav_src_loc, nav_val); @@ -3387,7 +3450,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo .generic_decl = .generic_decl_const, .decl_instance = .decl_instance_const, }, &nav, inst_info.file, &decl); - try wip_nav.strp(nav.fqn.toSlice(ip)); + try wip_nav.strp(switch (decl.linkage) { + .normal => nav.fqn, + .@"extern", .@"export" => nav.name, + }.toSlice(ip)); const nav_ty_reloc_index = try wip_nav.refForward(); try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse nav_ty.abiAlignment(zcu).toByteUnits().?); @@ -5109,6 +5175,8 @@ const AbbrevCode = enum { decl_func, decl_nullary_func_generic, decl_func_generic, + decl_extern_nullary_func, + decl_extern_func, generic_decl_var, generic_decl_const, generic_decl_func, @@ -5128,6 +5196,8 @@ const AbbrevCode = enum { decl_instance_func, decl_instance_nullary_func_generic, decl_instance_func_generic, + decl_instance_extern_nullary_func, + decl_instance_extern_func, // the rest are unrestricted other than empty variants must not be longer // than the non-empty variant, and so should appear first compile_unit, @@ -5179,6 +5249,9 @@ const AbbrevCode = enum { packed_struct_type, empty_union_type, union_type, + builtin_extern_nullary_func, + builtin_extern_func, + builtin_extern_var, empty_block, block, empty_inlined_func, @@ -5193,6 +5266,7 @@ const AbbrevCode = enum { unnamed_comptime_arg_comptime_state, comptime_arg_runtime_bits_comptime_state, unnamed_comptime_arg_runtime_bits_comptime_state, + extern_param, local_var, local_const, local_const_runtime_bits, @@ -5214,7 +5288,7 @@ const AbbrevCode = enum { comptime_value_elem_runtime_bits, comptime_value_elem_comptime_state, - const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_instance_func_generic)); + const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_instance_extern_func)); comptime { assert(uleb128Bytes(@intFromEnum(AbbrevCode.pad_1)) == 1); assert(uleb128Bytes(@intFromEnum(AbbrevCode.pad_n)) == 1); @@ -5389,6 +5463,27 @@ const AbbrevCode = enum { .{ .type, .ref_addr }, }, }, + .decl_extern_nullary_func = .{ + .tag = .subprogram, + .attrs = decl_abbrev_common_attrs ++ .{ + .{ .linkage_name, .strp }, + .{ .type, .ref_addr }, + .{ .low_pc, .addr }, + .{ .external, .flag_present }, + .{ .noreturn, .flag }, + }, + }, + .decl_extern_func = .{ + .tag = .subprogram, + .children = true, + .attrs = decl_abbrev_common_attrs ++ .{ + .{ .linkage_name, .strp }, + .{ .type, .ref_addr }, + .{ .low_pc, .addr }, + .{ .external, .flag_present }, + .{ .noreturn, .flag }, + }, + }, .generic_decl_var = .{ .tag = .variable, .attrs = generic_decl_abbrev_common_attrs, @@ -5537,6 +5632,27 @@ const AbbrevCode = enum { .{ .type, .ref_addr }, }, }, + .decl_instance_extern_nullary_func = .{ + .tag = .subprogram, + .attrs = decl_instance_abbrev_common_attrs ++ .{ + .{ .linkage_name, .strp }, + .{ .type, .ref_addr }, + .{ .low_pc, .addr }, + .{ .external, .flag_present }, + .{ .noreturn, .flag }, + }, + }, + .decl_instance_extern_func = .{ + .tag = .subprogram, + .children = true, + .attrs = decl_instance_abbrev_common_attrs ++ .{ + .{ .linkage_name, .strp }, + .{ .type, .ref_addr }, + .{ .low_pc, .addr }, + .{ .external, .flag_present }, + .{ .noreturn, .flag }, + }, + }, .compile_unit = .{ .tag = .compile_unit, .children = true, @@ -5934,6 +6050,39 @@ const AbbrevCode = enum { .{ .alignment, .udata }, }, }, + .builtin_extern_nullary_func = .{ + .tag = .subprogram, + .attrs = &.{ + .{ .ZIG_parent, .ref_addr }, + .{ .linkage_name, .strp }, + .{ .type, .ref_addr }, + .{ .low_pc, .addr }, + .{ .external, .flag_present }, + .{ .noreturn, .flag }, + }, + }, + .builtin_extern_func = .{ + .tag = .subprogram, + .children = true, + .attrs = &.{ + .{ .ZIG_parent, .ref_addr }, + .{ .linkage_name, .strp }, + .{ .type, .ref_addr }, + .{ .low_pc, .addr }, + .{ .external, .flag_present }, + .{ .noreturn, .flag }, + }, + }, + .builtin_extern_var = .{ + .tag = .variable, + .attrs = &.{ + .{ .ZIG_parent, .ref_addr }, + .{ .linkage_name, .strp }, + .{ .type, .ref_addr }, + .{ .location, .exprloc }, + .{ .external, .flag_present }, + }, + }, .empty_block = .{ .tag = .lexical_block, .attrs = &.{ @@ -6053,6 +6202,12 @@ const AbbrevCode = enum { .{ .ZIG_comptime_value, .ref_addr }, }, }, + .extern_param = .{ + .tag = .formal_parameter, + .attrs = &.{ + .{ .type, .ref_addr }, + }, + }, .local_var = .{ .tag = .variable, .attrs = &.{ diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index ac0d4526e5..20e5b3d2e3 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -1543,8 +1543,8 @@ pub fn updateNav( @"extern".lib_name.toSlice(ip), ); if (@"extern".is_threadlocal and elf_file.base.comp.config.any_non_single_threaded) self.symbol(sym_index).flags.is_tls = true; - if (self.dwarf) |*dwarf| dwarf: { - var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf; + if (self.dwarf) |*dwarf| { + var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index); defer debug_wip_nav.deinit(); dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index 2b31a761bf..138a0693c5 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -877,8 +877,8 @@ pub fn updateNav( const lib_name = @"extern".lib_name.toSlice(ip); const sym_index = try self.getGlobalSymbol(macho_file, name, lib_name); if (@"extern".is_threadlocal and macho_file.base.comp.config.any_non_single_threaded) self.symbols.items[sym_index].flags.tlv = true; - if (self.dwarf) |*dwarf| dwarf: { - var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf; + if (self.dwarf) |*dwarf| { + var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index); defer debug_wip_nav.deinit(); dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, diff --git a/test/behavior/extern.zig b/test/behavior/extern.zig index 9efb1c2137..7541a1957d 100644 --- a/test/behavior/extern.zig +++ b/test/behavior/extern.zig @@ -56,3 +56,16 @@ test "coerce extern function types" { _ = @as(fn () callconv(.c) ?*u32, c_extern_function); } + +fn a_function(func: fn () callconv(.c) void) void { + _ = func; +} + +test "pass extern function to function" { + a_function(struct { + extern fn an_extern_function() void; + }.an_extern_function); + a_function(@extern(*const fn () callconv(.c) void, .{ .name = "an_extern_function" }).*); +} + +export fn an_extern_function() void {} diff --git a/test/incremental/change_exports b/test/incremental/change_exports index e492930031..01605bdeeb 100644 --- a/test/incremental/change_exports +++ b/test/incremental/change_exports @@ -1,4 +1,4 @@ -#target=x86_64-linux-selfhosted +//#target=x86_64-linux-selfhosted #target=x86_64-linux-cbe #target=x86_64-windows-cbe