stage2: do not require function when evaluating typeOf

We only care about the instructions type; it will never actually be codegen'd.
This commit is contained in:
Veikka Tuominen 2022-02-26 18:06:06 +02:00
parent ff72b8a819
commit 315d4e8442
3 changed files with 20 additions and 10 deletions

View File

@ -13427,7 +13427,7 @@ fn zirBuiltinExtern(
}
fn requireFunctionBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
if (sema.func == null) {
if (sema.func == null and !block.is_typeof) {
return sema.fail(block, src, "instruction illegal outside function body", .{});
}
}
@ -14194,7 +14194,8 @@ fn fieldCallBind(
if (first_param_tag == .var_args_param or
first_param_tag == .generic_poison or (
first_param_type.zigTypeTag() == .Pointer and
first_param_type.ptrSize() == .One and
(first_param_type.ptrSize() == .One or
first_param_type.ptrSize() == .C) and
first_param_type.childType().eql(concrete_ty)))
{
// zig fmt: on

View File

@ -38,6 +38,7 @@ test {
_ = @import("behavior/bugs/3112.zig");
_ = @import("behavior/bugs/3367.zig");
_ = @import("behavior/bugs/3586.zig");
_ = @import("behavior/bugs/4328.zig");
_ = @import("behavior/bugs/4560.zig");
_ = @import("behavior/bugs/4769_a.zig");
_ = @import("behavior/bugs/4769_b.zig");
@ -150,7 +151,6 @@ test {
_ = @import("behavior/bugs/1851.zig");
_ = @import("behavior/bugs/3384.zig");
_ = @import("behavior/bugs/3779.zig");
_ = @import("behavior/bugs/4328.zig");
_ = @import("behavior/bugs/5398.zig");
_ = @import("behavior/bugs/5413.zig");
_ = @import("behavior/bugs/5487.zig");

View File

@ -1,4 +1,5 @@
const expectEqual = @import("std").testing.expectEqual;
const expect = @import("std").testing.expect;
const builtin = @import("builtin");
const FILE = extern struct {
dummy_field: u8,
@ -16,18 +17,20 @@ const S = extern struct {
};
test "Extern function calls in @TypeOf" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
const Test = struct {
fn test_fn_1(a: anytype, b: anytype) @TypeOf(printf("%d %s\n", a, b)) {
return 0;
}
fn test_fn_2(a: anytype) @TypeOf((S{ .state = 0 }).s_do_thing(a)) {
fn test_fn_2(s: anytype, a: anytype) @TypeOf(s.s_do_thing(a)) {
return 1;
}
fn doTheTest() !void {
try expectEqual(c_int, @TypeOf(test_fn_1(0, 42)));
try expectEqual(c_short, @TypeOf(test_fn_2(0)));
try expect(@TypeOf(test_fn_1(0, 42)) == c_int);
try expect(@TypeOf(test_fn_2(&S{ .state = 1 }, 0)) == c_short);
}
};
@ -36,13 +39,15 @@ test "Extern function calls in @TypeOf" {
}
test "Peer resolution of extern function calls in @TypeOf" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
const Test = struct {
fn test_fn() @TypeOf(ftell(null), fputs(null, null)) {
return 0;
}
fn doTheTest() !void {
try expectEqual(c_long, @TypeOf(test_fn()));
try expect(@TypeOf(test_fn()) == c_long);
}
};
@ -51,6 +56,10 @@ test "Peer resolution of extern function calls in @TypeOf" {
}
test "Extern function calls, dereferences and field access in @TypeOf" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
const Test = struct {
fn test_fn_1(a: c_long) @TypeOf(fopen("test", "r").*) {
_ = a;
@ -63,8 +72,8 @@ test "Extern function calls, dereferences and field access in @TypeOf" {
}
fn doTheTest() !void {
try expectEqual(FILE, @TypeOf(test_fn_1(0)));
try expectEqual(u8, @TypeOf(test_fn_2(0)));
try expect(@TypeOf(test_fn_1(0)) == FILE);
try expect(@TypeOf(test_fn_2(0)) == u8);
}
};