ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
35.2k stars 2.57k forks source link

Zig translate-c array translation bug #21192

Open devraymondsh opened 3 months ago

devraymondsh commented 3 months ago

Zig Version

0.14.0-dev.1294+df6907f60

Steps to Reproduce and Observed Behavior

I was trying to translate the io_uring.h file from Linux's uapi using Zig's translate-c. The header is dependent on ioctl.h and fscrypt.h. Here's the Zig translation:

// ...
pub const FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF = @as(c_int, 0x00000001);
pub const FS_IOC_SET_ENCRYPTION_POLICY = _IOR('f', @as(c_int, 19), struct_fscrypt_policy_v1);
pub const FS_IOC_GET_ENCRYPTION_PWSALT = _IOW('f', @as(c_int, 20), __u8[@as(usize, @intCast(@as(c_int, 16)))]);
pub const FS_IOC_GET_ENCRYPTION_POLICY = _IOW('f', @as(c_int, 21), struct_fscrypt_policy_v1);
pub const FS_IOC_GET_ENCRYPTION_POLICY_EX = _IOWR('f', @as(c_int, 22), __u8[@as(usize, @intCast(@as(c_int, 9)))]);
pub const FS_IOC_ADD_ENCRYPTION_KEY = _IOWR('f', @as(c_int, 23), struct_fscrypt_add_key_arg);
pub const FS_IOC_REMOVE_ENCRYPTION_KEY = _IOWR('f', @as(c_int, 24), struct_fscrypt_remove_key_arg);
pub const FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS = _IOWR('f', @as(c_int, 25), struct_fscrypt_remove_key_arg);
pub const FS_IOC_GET_ENCRYPTION_KEY_STATUS = _IOWR('f', @as(c_int, 26), struct_fscrypt_get_key_status_arg);
pub const FS_IOC_GET_ENCRYPTION_NONCE = _IOR('f', @as(c_int, 27), __u8[@as(usize, @intCast(@as(c_int, 16)))]);
// ...

I get this error:

.zig-cache/o/049deb9fa5e484306b375e323e26be2a/io_uring.zig:1315:72: error: type 'type' does not support indexing
pub const FS_IOC_GET_ENCRYPTION_PWSALT = _IOW('f', @as(c_int, 20), __u8[@as(usize, @intCast(@as(c_int, 16)))]);
                                                                   ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.zig-cache/o/049deb9fa5e484306b375e323e26be2a/io_uring.zig:1315:72: note: operand must be an array, slice, tuple, or vector

It's basically translating this line but generates __u8[16] instead of [16]__u8 which is the correct Zig equivalent.

Expected Behavior

Should have become [16]__u8 which is the correct translation.

devraymondsh commented 3 months ago

Reproduce this problem by translating C with zig translate-c -lc macro_fn_arr_ty.c > macro_fn_arr_ty.zig. macro_fn_arr_ty.c:

#define G(T) T
#define F G(unsigned char[1])

Append boilerplate:

export fn entry() void {
    _ = &F;
}

Compile example program with zig build-obj macro_fn_arr_ty.zig.

Will face this error:

macro_fn_arr_ty.zig:498:19: error: type 'type' does not support indexing
pub const F = G(u8[@as(usize, @intCast(@as(c_int, 1)))]);
                ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
macro_fn_arr_ty.zig:498:19: note: operand must be an array, slice, tuple, or vector
referenced by:
    entry: macro_fn_arr_ty.zig:500:10
    entry: macro_fn_arr_ty.zig:499:1
    4 reference(s) hidden; use '-freference-trace=6' to see all references