authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-12-28 00:50:17+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-12-28 00:50:17+01:00
loga38704d0122d5dd91011541d187d1fc115265a7c
tree0e03cadb79cedc8666974fa16bcc529e08d60299
parent25e71216c4640a3d88c8f63912ea574ad6fa004c

Fix crash in translate-c w/ parameterless fn


2 files changed, 38 insertions(+), 7 deletions(-)

src-self-hosted/translate_c.zig+28-5
...@@ -2145,7 +2145,7 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr,...@@ -2145,7 +2145,7 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr,
2145 node.rtoken = try appendToken(rp.c, .RParen, ")");2145 node.rtoken = try appendToken(rp.c, .RParen, ")");
21462146
2147 if (fn_ty) |ty| {2147 if (fn_ty) |ty| {
2148 const canon = ZigClangQualType_getCanonicalType(ZigClangFunctionProtoType_getReturnType(ty));2148 const canon = ZigClangQualType_getCanonicalType(ty.getReturnType());
2149 const ret_ty = ZigClangQualType_getTypePtr(canon);2149 const ret_ty = ZigClangQualType_getTypePtr(canon);
2150 if (ZigClangType_isVoidType(ret_ty)) {2150 if (ZigClangType_isVoidType(ret_ty)) {
2151 _ = try appendToken(rp.c, .Semicolon, ";");2151 _ = try appendToken(rp.c, .Semicolon, ";");
...@@ -2156,7 +2156,19 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr,...@@ -2156,7 +2156,19 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr,
2156 return maybeSuppressResult(rp, scope, result_used, &node.base);2156 return maybeSuppressResult(rp, scope, result_used, &node.base);
2157}2157}
21582158
2159fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?*const ZigClangFunctionProtoType {2159const ClangFunctionType = union(enum) {
2160 Proto: *const ZigClangFunctionProtoType,
2161 NoProto: *const ZigClangFunctionType,
2162
2163 fn getReturnType(self: @This()) ZigClangQualType {
2164 switch (@as(@TagType(@This()), self)) {
2165 .Proto => return ZigClangFunctionProtoType_getReturnType(self.Proto),
2166 .NoProto => return ZigClangFunctionType_getReturnType(self.NoProto),
2167 }
2168 }
2169};
2170
2171fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?ClangFunctionType {
2160 const canon = ZigClangQualType_getCanonicalType(qt);2172 const canon = ZigClangQualType_getCanonicalType(qt);
2161 var ty = ZigClangQualType_getTypePtr(canon);2173 var ty = ZigClangQualType_getTypePtr(canon);
2162 is_ptr.* = false;2174 is_ptr.* = false;
...@@ -2167,7 +2179,10 @@ fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?*const ZigClangFunct...@@ -2167,7 +2179,10 @@ fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?*const ZigClangFunct
2167 ty = ZigClangQualType_getTypePtr(child_qt);2179 ty = ZigClangQualType_getTypePtr(child_qt);
2168 }2180 }
2169 if (ZigClangType_getTypeClass(ty) == .FunctionProto) {2181 if (ZigClangType_getTypeClass(ty) == .FunctionProto) {
2170 return @ptrCast(*const ZigClangFunctionProtoType, ty);2182 return ClangFunctionType{ .Proto = @ptrCast(*const ZigClangFunctionProtoType, ty) };
2183 }
2184 if (ZigClangType_getTypeClass(ty) == .FunctionNoProto) {
2185 return ClangFunctionType{ .NoProto = @ptrCast(*const ZigClangFunctionType, ty) };
2171 }2186 }
2172 return null;2187 return null;
2173}2188}
...@@ -2771,7 +2786,10 @@ fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool {...@@ -2771,7 +2786,10 @@ fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool {
2771 .Paren => {2786 .Paren => {
2772 const paren_type = @ptrCast(*const ZigClangParenType, ty);2787 const paren_type = @ptrCast(*const ZigClangParenType, ty);
2773 const inner_type = ZigClangParenType_getInnerType(paren_type);2788 const inner_type = ZigClangParenType_getInnerType(paren_type);
2774 return ZigClangQualType_getTypeClass(inner_type) == .FunctionProto;2789 switch (ZigClangQualType_getTypeClass(inner_type)) {
2790 .FunctionProto, .FunctionNoProto => return true,
2791 else => return false,
2792 }
2775 },2793 },
2776 .Attributed => {2794 .Attributed => {
2777 const attr_type = @ptrCast(*const ZigClangAttributedType, ty);2795 const attr_type = @ptrCast(*const ZigClangAttributedType, ty);
...@@ -3571,11 +3589,16 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour...@@ -3571,11 +3589,16 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
3571 else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),3589 else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),
3572 });3590 });
3573 },3591 },
3574 .FunctionProto, .FunctionNoProto => {3592 .FunctionProto => {
3575 const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty);3593 const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty);
3576 const fn_proto = try transFnProto(rp, null, fn_proto_ty, source_loc, null, false);3594 const fn_proto = try transFnProto(rp, null, fn_proto_ty, source_loc, null, false);
3577 return &fn_proto.base;3595 return &fn_proto.base;
3578 },3596 },
3597 .FunctionNoProto => {
3598 const fn_no_proto_ty = @ptrCast(*const ZigClangFunctionType, ty);
3599 const fn_proto = try transFnNoProto(rp, fn_no_proto_ty, source_loc, null, false);
3600 return &fn_proto.base;
3601 },
3579 .Paren => {3602 .Paren => {
3580 const paren_ty = @ptrCast(*const ZigClangParenType, ty);3603 const paren_ty = @ptrCast(*const ZigClangParenType, ty);
3581 return transQualType(rp, ZigClangParenType_getInnerType(paren_ty), source_loc);3604 return transQualType(rp, ZigClangParenType_getInnerType(paren_ty), source_loc);
test/translate_c.zig+10-2
...@@ -814,6 +814,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -814,6 +814,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
814814
815 /////////////// Cases that pass for only stage2 ////////////////815 /////////////// Cases that pass for only stage2 ////////////////
816816
817 cases.add_2("Parameterless function pointers",
818 \\typedef void (*fn0)();
819 \\typedef void (*fn1)(char);
820 , &[_][]const u8{
821 \\pub const fn0 = ?extern fn (...) void;
822 \\pub const fn1 = ?extern fn (u8) void;
823 });
824
817 cases.add_2("Parameterless function prototypes",825 cases.add_2("Parameterless function prototypes",
818 \\void a() {}826 \\void a() {}
819 \\void b(void) {}827 \\void b(void) {}
...@@ -1024,7 +1032,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1024,7 +1032,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1024 \\pub inline fn glClearUnion(arg_2: GLbitfield) void {1032 \\pub inline fn glClearUnion(arg_2: GLbitfield) void {
1025 \\ return glProcs.gl.Clear.?(arg_2);1033 \\ return glProcs.gl.Clear.?(arg_2);
1026 \\}1034 \\}
1027 ,1035 ,
1028 \\pub const OpenGLProcs = union_OpenGLProcs;1036 \\pub const OpenGLProcs = union_OpenGLProcs;
1029 });1037 });
10301038
...@@ -2166,7 +2174,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2166,7 +2174,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2166 });2174 });
21672175
2168 cases.add_2("macro cast",2176 cases.add_2("macro cast",
2169 \\#define FOO(bar) baz((void *)(baz))2177 \\#define FOO(bar) baz((void *)(baz))
2170 , &[_][]const u8{2178 , &[_][]const u8{
2171 \\pub inline fn FOO(bar: var) @TypeOf(baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast([*c]void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr([*c]void, baz) else @as([*c]void, baz))) {2179 \\pub inline fn FOO(bar: var) @TypeOf(baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast([*c]void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr([*c]void, baz) else @as([*c]void, baz))) {
2172 \\ return baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast([*c]void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr([*c]void, baz) else @as([*c]void, baz));2180 \\ return baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast([*c]void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr([*c]void, baz) else @as([*c]void, baz));