mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Merge pull request #24249 from antlilja/dwarf-extern-arg
Fix compiler crash when passing a comptime extern function arg to a function
This commit is contained in:
commit
001ec07772
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
},
|
||||
|
||||
@ -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);
|
||||
},
|
||||
.@"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));
|
||||
},
|
||||
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));
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
.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 = &.{
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 {}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#target=x86_64-linux-selfhosted
|
||||
//#target=x86_64-linux-selfhosted
|
||||
#target=x86_64-linux-cbe
|
||||
#target=x86_64-windows-cbe
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user