authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-11 17:56:37+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-12 15:41:29+02:00
logd42f4abb9dc906ef20b622656c7672cb7df02096
treefa5bc68b71fe6b180e28abe2bf31a1b44dfb63c0
parente01ec96288bd32c7ec3bba01ee200cc115cdfb1d

llvm: correctly lower references to generic functions

Closes #13522

2 files changed, 22 insertions(+), 2 deletions(-)

src/codegen/llvm.zig+5-2
...@@ -3198,7 +3198,8 @@ pub const DeclGen = struct {...@@ -3198,7 +3198,8 @@ pub const DeclGen = struct {
3198 /// There are other similar cases handled here as well.3198 /// There are other similar cases handled here as well.
3199 fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*llvm.Type {3199 fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*llvm.Type {
3200 const lower_elem_ty = switch (elem_ty.zigTypeTag()) {3200 const lower_elem_ty = switch (elem_ty.zigTypeTag()) {
3201 .Opaque, .Fn => true,3201 .Opaque => true,
3202 .Fn => !elem_ty.fnInfo().is_generic,
3202 .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(),3203 .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(),
3203 else => elem_ty.hasRuntimeBitsIgnoreComptime(),3204 else => elem_ty.hasRuntimeBitsIgnoreComptime(),
3204 };3205 };
...@@ -4145,7 +4146,9 @@ pub const DeclGen = struct {...@@ -4145,7 +4146,9 @@ pub const DeclGen = struct {
4145 }4146 }
41464147
4147 const is_fn_body = decl.ty.zigTypeTag() == .Fn;4148 const is_fn_body = decl.ty.zigTypeTag() == .Fn;
4148 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {4149 if ((!is_fn_body and !decl.ty.hasRuntimeBits()) or
4150 (is_fn_body and decl.ty.fnInfo().is_generic))
4151 {
4149 return self.lowerPtrToVoid(tv.ty);4152 return self.lowerPtrToVoid(tv.ty);
4150 }4153 }
41514154
test/behavior/pointers.zig+17
...@@ -489,3 +489,20 @@ test "ptrCast comptime known slice to C pointer" {...@@ -489,3 +489,20 @@ test "ptrCast comptime known slice to C pointer" {
489 var p = @ptrCast([*c]const u8, s);489 var p = @ptrCast([*c]const u8, s);
490 try std.testing.expectEqualStrings(s, std.mem.sliceTo(p, 0));490 try std.testing.expectEqualStrings(s, std.mem.sliceTo(p, 0));
491}491}
492
493test "ptrToInt on a generic function" {
494 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
495 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
496 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag != .linux) return error.SkipZigTest; // TODO
497 if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag != .linux) return error.SkipZigTest; // TODO
498
499 const S = struct {
500 fn generic(i: anytype) @TypeOf(i) {
501 return i;
502 }
503 fn doTheTest(a: anytype) !void {
504 try expect(@ptrToInt(a) != 0);
505 }
506 };
507 try S.doTheTest(&S.generic);
508}