stage2 llvm: fix lowerDeclRefValue for function aliases
This commit is contained in:
committed by
Andrew Kelley
parent
b48d8cce52
commit
0577069af5
@@ -762,7 +762,6 @@ fn formatFloatValue(
|
||||
if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "e")) {
|
||||
formatFloatScientific(value, options, buf_stream.writer()) catch |err| switch (err) {
|
||||
error.NoSpaceLeft => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
} else if (comptime std.mem.eql(u8, fmt, "d")) {
|
||||
formatFloatDecimal(value, options, buf_stream.writer()) catch |err| switch (err) {
|
||||
|
||||
@@ -1080,13 +1080,8 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
|
||||
const mask_size = @sizeOf(@TypeOf(ksa.mask));
|
||||
|
||||
if (act) |new| {
|
||||
const restore_rt_ptr = if (builtin.zig_backend == .stage1) restore_rt else &syscall_bits.restore_rt;
|
||||
// TODO https://github.com/ziglang/zig/issues/11227
|
||||
const restore_ptr = if (builtin.zig_backend == .stage1) restore else switch (native_arch) {
|
||||
.arm, .thumb, .mips, .mipsel, .i386 => &syscall_bits.restore,
|
||||
.x86_64, .aarch64, .riscv64, .sparcv9, .powerpc, .powerpc64, .powerpc64le => &syscall_bits.restore_rt,
|
||||
else => unreachable,
|
||||
};
|
||||
const restore_rt_ptr = if (builtin.zig_backend == .stage1) restore_rt else &restore_rt;
|
||||
const restore_ptr = if (builtin.zig_backend == .stage1) restore else &restore;
|
||||
const restorer_fn = if ((new.flags & SA.SIGINFO) != 0) restore_rt_ptr else restore_ptr;
|
||||
ksa = k_sigaction{
|
||||
.handler = new.handler.handler,
|
||||
|
||||
@@ -3073,6 +3073,17 @@ pub const DeclGen = struct {
|
||||
return self.context.constStruct(&fields, fields.len, .False);
|
||||
}
|
||||
|
||||
// In the case of something like:
|
||||
// fn foo() void {}
|
||||
// const bar = foo;
|
||||
// ... &bar;
|
||||
// `bar` is just an alias and we actually want to lower a reference to `foo`.
|
||||
if (decl.val.castTag(.function)) |func| {
|
||||
if (func.data.owner_decl != decl) {
|
||||
return self.lowerDeclRefValue(tv, func.data.owner_decl);
|
||||
}
|
||||
}
|
||||
|
||||
const is_fn_body = decl.ty.zigTypeTag() == .Fn;
|
||||
if (!is_fn_body and !decl.ty.hasRuntimeBitsIgnoreComptime()) {
|
||||
return self.lowerPtrToVoid(tv.ty);
|
||||
|
||||
@@ -161,6 +161,7 @@ test {
|
||||
builtin.zig_backend != .stage2_wasm and
|
||||
builtin.zig_backend != .stage2_c)
|
||||
{
|
||||
_ = @import("behavior/bugs/11227.zig");
|
||||
_ = @import("behavior/export.zig");
|
||||
_ = @import("behavior/export_self_referential_type_info.zig");
|
||||
}
|
||||
|
||||
13
test/behavior/bugs/11227.zig
Normal file
13
test/behavior/bugs/11227.zig
Normal file
@@ -0,0 +1,13 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
fn foo() u32 {
|
||||
return 11227;
|
||||
}
|
||||
const bar = foo;
|
||||
test "pointer to alias behaves same as pointer to function" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest; // stage1 has different function pointers
|
||||
|
||||
var a = &bar;
|
||||
try std.testing.expect(foo() == a());
|
||||
}
|
||||
@@ -2,15 +2,20 @@ const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const S = struct {
|
||||
f: ?fn () i32,
|
||||
f: ?*const fn () i32,
|
||||
};
|
||||
|
||||
const s = S{ .f = f };
|
||||
const s = S{ .f = &f };
|
||||
|
||||
fn f() i32 {
|
||||
return 1234;
|
||||
}
|
||||
|
||||
test "don't emit an LLVM global for a const function when it's in an optional in a struct" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest; // stage1 has different function pointers
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
||||
try std.testing.expect(s.f.?() == 1234);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user