stage2 llvm: fix lowerDeclRefValue for function aliases

This commit is contained in:
Veikka Tuominen
2022-03-21 13:25:57 +02:00
committed by Andrew Kelley
parent b48d8cce52
commit 0577069af5
6 changed files with 34 additions and 10 deletions

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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);

View File

@@ -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");
}

View 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());
}

View File

@@ -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);
}