translate-c: Fix casting of function pointers
The @ptrCast(X, @alignCast(@alignOf(T), Y)) pattern is only correct if T is not a function type or a pointer, in that case the @alignOf refers to the pointer itself and not to the pointee type.
This commit is contained in:
@@ -3539,7 +3539,7 @@ fn transCPtrCast(
|
||||
expr
|
||||
else blk: {
|
||||
const child_type_node = try transQualType(c, scope, child_type, loc);
|
||||
const alignof = try Tag.alignof.create(c.arena, child_type_node);
|
||||
const alignof = try Tag.std_meta_alignment.create(c.arena, child_type_node);
|
||||
const align_cast = try Tag.align_cast.create(c.arena, .{ .lhs = alignof, .rhs = expr });
|
||||
break :blk align_cast;
|
||||
};
|
||||
|
||||
@@ -120,8 +120,11 @@ pub const Node = extern union {
|
||||
std_math_Log2Int,
|
||||
/// @intCast(lhs, rhs)
|
||||
int_cast,
|
||||
/// @rem(lhs, rhs)
|
||||
/// @import("std").meta.promoteIntLiteral(value, type, radix)
|
||||
std_meta_promoteIntLiteral,
|
||||
/// @import("std").meta.alignment(value)
|
||||
std_meta_alignment,
|
||||
/// @rem(lhs, rhs)
|
||||
rem,
|
||||
/// @divTrunc(lhs, rhs)
|
||||
div_trunc,
|
||||
@@ -260,6 +263,7 @@ pub const Node = extern union {
|
||||
.switch_else,
|
||||
.block_single,
|
||||
.std_meta_sizeof,
|
||||
.std_meta_alignment,
|
||||
.bool_to_int,
|
||||
.sizeof,
|
||||
.alignof,
|
||||
@@ -876,6 +880,11 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
const import_node = try renderStdImport(c, "meta", "promoteIntLiteral");
|
||||
return renderCall(c, import_node, &.{ payload.type, payload.value, payload.radix });
|
||||
},
|
||||
.std_meta_alignment => {
|
||||
const payload = node.castTag(.std_meta_alignment).?.data;
|
||||
const import_node = try renderStdImport(c, "meta", "alignment");
|
||||
return renderCall(c, import_node, &.{payload});
|
||||
},
|
||||
.std_meta_sizeof => {
|
||||
const payload = node.castTag(.std_meta_sizeof).?.data;
|
||||
const import_node = try renderStdImport(c, "meta", "sizeof");
|
||||
@@ -2144,6 +2153,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
|
||||
.typeof,
|
||||
.typeinfo,
|
||||
.std_meta_sizeof,
|
||||
.std_meta_alignment,
|
||||
.std_meta_cast,
|
||||
.std_meta_promoteIntLiteral,
|
||||
.std_meta_vector,
|
||||
|
||||
@@ -1363,7 +1363,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub export fn ptrcast() [*c]f32 {
|
||||
\\ var a: [*c]c_int = undefined;
|
||||
\\ return @ptrCast([*c]f32, @alignCast(@alignOf(f32), a));
|
||||
\\ return @ptrCast([*c]f32, @alignCast(@import("std").meta.alignment(f32), a));
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -1387,16 +1387,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub export fn test_ptr_cast() void {
|
||||
\\ var p: ?*c_void = undefined;
|
||||
\\ {
|
||||
\\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@alignOf(u8), p));
|
||||
\\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@alignOf(c_short), p));
|
||||
\\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@alignOf(c_int), p));
|
||||
\\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@alignOf(c_longlong), p));
|
||||
\\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@import("std").meta.alignment(u8), p));
|
||||
\\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@import("std").meta.alignment(c_short), p));
|
||||
\\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@import("std").meta.alignment(c_int), p));
|
||||
\\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@import("std").meta.alignment(c_longlong), p));
|
||||
\\ }
|
||||
\\ {
|
||||
\\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@alignOf(u8), p));
|
||||
\\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@alignOf(c_short), p));
|
||||
\\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@alignOf(c_int), p));
|
||||
\\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@alignOf(c_longlong), p));
|
||||
\\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@import("std").meta.alignment(u8), p));
|
||||
\\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@import("std").meta.alignment(c_short), p));
|
||||
\\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@import("std").meta.alignment(c_int), p));
|
||||
\\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@import("std").meta.alignment(c_longlong), p));
|
||||
\\ }
|
||||
\\}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user