Commit d42f4abb9d

Veikka Tuominen <git@vexu.eu>
2022-11-11 16:56:37
llvm: correctly lower references to generic functions
Closes #13522
1 parent e01ec96
Changed files (2)
src
codegen
test
behavior
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);
         }
 
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);
+}