From fd023fe5e2cd4f729176cb070b7972f227706195 Mon Sep 17 00:00:00 2001 From: paokito Date: Mon, 21 Jul 2025 11:08:54 +0200 Subject: [PATCH 1/3] translate-c: fix function pointers casting --- src/translate_c.zig | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/translate_c.zig b/src/translate_c.zig index f1f3ad865946..0b60fb0e7d27 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -4030,7 +4030,10 @@ fn transCPtrCast( const src_child_type = src_ty.getPointeeType(); const dst_type_node = try transType(c, scope, ty, loc); - if (!src_ty.isArrayType() and ((src_child_type.isConstQualified() and + if (!src_ty.isArrayType() and ((( + src_child_type.isConstQualified() or + qualTypeIsFunction(src_child_type) // C function pointers get translated to Zig const function pointers + ) and !child_type.isConstQualified()) or (src_child_type.isVolatileQualified() and !child_type.isVolatileQualified()))) @@ -4342,6 +4345,11 @@ fn qualTypeIsBoolean(qt: clang.QualType) bool { return qualTypeCanon(qt).isBooleanType(); } +fn qualTypeIsFunction(qt: clang.QualType) bool { + const type_class = qualTypeCanon(qt).getTypeClass(); + return type_class == .FunctionProto or type_class == .FunctionNoProto; +} + fn qualTypeIntBitWidth(c: *Context, qt: clang.QualType) !u32 { const ty = qt.getTypePtr(); From c63a69a14ecb9cb14163022359ad6bb1d51089d1 Mon Sep 17 00:00:00 2001 From: paokito Date: Mon, 21 Jul 2025 11:09:55 +0200 Subject: [PATCH 2/3] translate-c: allow constCast and alignCast at the same time --- src/translate_c.zig | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/translate_c.zig b/src/translate_c.zig index 0b60fb0e7d27..48996886cb8e 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -4030,6 +4030,18 @@ fn transCPtrCast( const src_child_type = src_ty.getPointeeType(); const dst_type_node = try transType(c, scope, ty, loc); + // Implicit downcasting from higher to lower alignment values is forbidden, + // use @alignCast to side-step this problem + const rhs = if (qualTypeCanon(child_type).isVoidType()) + // void has 1-byte alignment, so @alignCast is not needed + expr + else if (typeIsOpaque(c, qualTypeCanon(child_type), loc)) + // For opaque types a ptrCast is enough + expr + else blk: { + break :blk try Tag.align_cast.create(c.arena, expr); + }; + if (!src_ty.isArrayType() and ((( src_child_type.isConstQualified() or qualTypeIsFunction(src_child_type) // C function pointers get translated to Zig const function pointers @@ -4038,19 +4050,8 @@ fn transCPtrCast( (src_child_type.isVolatileQualified() and !child_type.isVolatileQualified()))) { - return removeCVQualifiers(c, dst_type_node, expr); + return removeCVQualifiers(c, dst_type_node, rhs); } else { - // Implicit downcasting from higher to lower alignment values is forbidden, - // use @alignCast to side-step this problem - const rhs = if (qualTypeCanon(child_type).isVoidType()) - // void has 1-byte alignment, so @alignCast is not needed - expr - else if (typeIsOpaque(c, qualTypeCanon(child_type), loc)) - // For opaque types a ptrCast is enough - expr - else blk: { - break :blk try Tag.align_cast.create(c.arena, expr); - }; return Tag.as.create(c.arena, .{ .lhs = dst_type_node, .rhs = try Tag.ptr_cast.create(c.arena, rhs), From 9737749e1c69763a84f634ad03628f5b77673b17 Mon Sep 17 00:00:00 2001 From: paokito Date: Sun, 3 Aug 2025 22:59:43 +0200 Subject: [PATCH 3/3] fix formatting --- src/translate_c.zig | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/translate_c.zig b/src/translate_c.zig index 48996886cb8e..959855311821 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -4042,13 +4042,11 @@ fn transCPtrCast( break :blk try Tag.align_cast.create(c.arena, expr); }; - if (!src_ty.isArrayType() and ((( - src_child_type.isConstQualified() or - qualTypeIsFunction(src_child_type) // C function pointers get translated to Zig const function pointers - ) and - !child_type.isConstQualified()) or - (src_child_type.isVolatileQualified() and - !child_type.isVolatileQualified()))) + if (!src_ty.isArrayType() and + (((src_child_type.isConstQualified() or qualTypeIsFunction(src_child_type)) and + !child_type.isConstQualified()) or + (src_child_type.isVolatileQualified() and + !child_type.isVolatileQualified()))) { return removeCVQualifiers(c, dst_type_node, rhs); } else {