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 {
31983198 /// There are other similar cases handled here as well.
31993199 fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*llvm.Type {
32003200 const lower_elem_ty = switch (elem_ty.zigTypeTag()) {
3201 .Opaque, .Fn => true,
3201 .Opaque => true,
3202 .Fn => !elem_ty.fnInfo().is_generic,
32023203 .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(),
32033204 else => elem_ty.hasRuntimeBitsIgnoreComptime(),
32043205 };
......@@ -4145,7 +4146,9 @@ pub const DeclGen = struct {
41454146 }
41464147
41474148 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 {
41494152 return self.lowerPtrToVoid(tv.ty);
41504153 }
41514154
test/behavior/pointers.zig+17
......@@ -489,3 +489,20 @@ test "ptrCast comptime known slice to C pointer" {
489489 var p = @ptrCast([*c]const u8, s);
490490 try std.testing.expectEqualStrings(s, std.mem.sliceTo(p, 0));
491491}
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}