From a284be3f69aabb13ad64753e03601169e8292a24 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 20 Jan 2020 23:13:20 +0100 Subject: [PATCH] Fix unsafe cast in translate_c Fixes #4250 --- src-self-hosted/clang.zig | 1 + src-self-hosted/translate_c.zig | 3 ++- src/zig_clang.cpp | 5 +++++ src/zig_clang.h | 1 + test/translate_c.zig | 25 +++++++++++++++++++++++++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 37f1eebe27424999b69aac16350b0ead74d41d8a..a569113b9d3c3e9a7d0dd78a72f232241d2b5fc2 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -809,6 +809,7 @@ pub extern fn ZigClangQualType_isRestrictQualified(self: struct_ZigClangQualType pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass; pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) struct_ZigClangQualType; pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool; +pub extern fn ZigClangType_isConstantArrayType(self: ?*const struct_ZigClangType) bool; pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool; pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool; pub extern fn ZigClangType_isBooleanType(self: ?*const struct_ZigClangType) bool; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index bade253a074859e25d125fc14d3a033499505262..093acf1083f7e5c6a7bcd7fa3d61452c3e0d4e6a 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -1982,7 +1982,8 @@ fn transInitListExprArray( const arr_type = ZigClangType_getAsArrayTypeUnsafe(ty); const child_qt = ZigClangArrayType_getElementType(arr_type); const init_count = ZigClangInitListExpr_getNumInits(expr); - const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, ty); + assert(ZigClangType_isConstantArrayType(@ptrCast(*const ZigClangType, arr_type))); + const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, arr_type); const size_ap_int = ZigClangConstantArrayType_getSize(const_arr_ty); const all_count = ZigClangAPInt_getLimitedValue(size_ap_int, math.maxInt(usize)); const leftover_count = all_count - init_count; diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 5769d2fc73ccbc4291e02bba92c684ab24ff65de..348c85b87ba0579c2421ee7f69d3836ee6df341e 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1877,6 +1877,11 @@ bool ZigClangType_isRecordType(const ZigClangType *self) { return casted->isRecordType(); } +bool ZigClangType_isConstantArrayType(const ZigClangType *self) { + auto casted = reinterpret_cast(self); + return casted->isConstantArrayType(); +} + const char *ZigClangType_getTypeClassName(const ZigClangType *self) { auto casted = reinterpret_cast(self); return casted->getTypeClassName(); diff --git a/src/zig_clang.h b/src/zig_clang.h index f9ced941cbf2bda9f7969607aa41ec7d6c49a4ba..6f8d786bf6bf51ed418d7f5b65d44a4d43ffe67c 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -945,6 +945,7 @@ ZIG_EXTERN_C bool ZigClangType_isBooleanType(const struct ZigClangType *self); ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self); ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self); ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self); +ZIG_EXTERN_C bool ZigClangType_isConstantArrayType(const ZigClangType *self); ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self); ZIG_EXTERN_C const struct ZigClangArrayType *ZigClangType_getAsArrayTypeUnsafe(const struct ZigClangType *self); ZIG_EXTERN_C const ZigClangRecordType *ZigClangType_getAsRecordType(const ZigClangType *self); diff --git a/test/translate_c.zig b/test/translate_c.zig index df33d9b145f14fb9baab40bea31bbf70d51708de..df2c872bf909d8e02a179d909497b8df9db5cddc 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -2,6 +2,31 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.TranslateCContext) void { + cases.add("array initializer w/ typedef", + \\typedef unsigned char uuid_t[16]; + \\static const uuid_t UUID_NULL __attribute__ ((unused)) = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + , &[_][]const u8{ + \\pub const uuid_t = [16]u8; + \\pub const UUID_NULL: uuid_t = .{ + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), + \\}; + }); + cases.add("empty declaration", \\; , &[_][]const u8{""}); -- 2.54.0