diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-11-11 17:56:37 +0200 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2022-11-12 15:41:29 +0200 |
| commit | d42f4abb9dc906ef20b622656c7672cb7df02096 (patch) | |
| tree | fa5bc68b71fe6b180e28abe2bf31a1b44dfb63c0 | |
| parent | e01ec96288bd32c7ec3bba01ee200cc115cdfb1d (diff) | |
| download | zig-d42f4abb9dc906ef20b622656c7672cb7df02096.tar.gz zig-d42f4abb9dc906ef20b622656c7672cb7df02096.zip | |
llvm: correctly lower references to generic functions
Closes #13522
| -rw-r--r-- | src/codegen/llvm.zig | 7 | ||||
| -rw-r--r-- | test/behavior/pointers.zig | 17 |
2 files changed, 22 insertions, 2 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 2daad01936..506c34af1d 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3198,7 +3198,8 @@ pub const DeclGen = struct { /// There are other similar cases handled here as well. fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*llvm.Type { const lower_elem_ty = switch (elem_ty.zigTypeTag()) { - .Opaque, .Fn => true, + .Opaque => true, + .Fn => !elem_ty.fnInfo().is_generic, .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(), else => elem_ty.hasRuntimeBitsIgnoreComptime(), }; @@ -4145,7 +4146,9 @@ pub const DeclGen = struct { } const is_fn_body = decl.ty.zigTypeTag() == .Fn; - if (!is_fn_body and !decl.ty.hasRuntimeBits()) { + if ((!is_fn_body and !decl.ty.hasRuntimeBits()) or + (is_fn_body and decl.ty.fnInfo().is_generic)) + { return self.lowerPtrToVoid(tv.ty); } diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index 8ee7b5142a..43e62fdc93 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -489,3 +489,20 @@ test "ptrCast comptime known slice to C pointer" { var p = @ptrCast([*c]const u8, s); try std.testing.expectEqualStrings(s, std.mem.sliceTo(p, 0)); } + +test "ptrToInt on a generic function" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag != .linux) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag != .linux) return error.SkipZigTest; // TODO + + const S = struct { + fn generic(i: anytype) @TypeOf(i) { + return i; + } + fn doTheTest(a: anytype) !void { + try expect(@ptrToInt(a) != 0); + } + }; + try S.doTheTest(&S.generic); +} |
