Skip to content

Commit a38704d

Browse files
committed
Fix crash in translate-c w/ parameterless fn
1 parent 25e7121 commit a38704d

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

src-self-hosted/translate_c.zig

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,7 +2145,7 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr,
21452145
node.rtoken = try appendToken(rp.c, .RParen, ")");
21462146

21472147
if (fn_ty) |ty| {
2148-
const canon = ZigClangQualType_getCanonicalType(ZigClangFunctionProtoType_getReturnType(ty));
2148+
const canon = ZigClangQualType_getCanonicalType(ty.getReturnType());
21492149
const ret_ty = ZigClangQualType_getTypePtr(canon);
21502150
if (ZigClangType_isVoidType(ret_ty)) {
21512151
_ = try appendToken(rp.c, .Semicolon, ";");
@@ -2156,7 +2156,19 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr,
21562156
return maybeSuppressResult(rp, scope, result_used, &node.base);
21572157
}
21582158

2159-
fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?*const ZigClangFunctionProtoType {
2159+
const 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+
2171+
fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?ClangFunctionType {
21602172
const canon = ZigClangQualType_getCanonicalType(qt);
21612173
var ty = ZigClangQualType_getTypePtr(canon);
21622174
is_ptr.* = false;
@@ -2167,7 +2179,10 @@ fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?*const ZigClangFunct
21672179
ty = ZigClangQualType_getTypePtr(child_qt);
21682180
}
21692181
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) };
21712186
}
21722187
return null;
21732188
}
@@ -2771,7 +2786,10 @@ fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool {
27712786
.Paren => {
27722787
const paren_type = @ptrCast(*const ZigClangParenType, ty);
27732788
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+
}
27752793
},
27762794
.Attributed => {
27772795
const attr_type = @ptrCast(*const ZigClangAttributedType, ty);
@@ -3571,11 +3589,16 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
35713589
else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),
35723590
});
35733591
},
3574-
.FunctionProto, .FunctionNoProto => {
3592+
.FunctionProto => {
35753593
const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty);
35763594
const fn_proto = try transFnProto(rp, null, fn_proto_ty, source_loc, null, false);
35773595
return &fn_proto.base;
35783596
},
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+
},
35793602
.Paren => {
35803603
const paren_ty = @ptrCast(*const ZigClangParenType, ty);
35813604
return transQualType(rp, ZigClangParenType_getInnerType(paren_ty), source_loc);

test/translate_c.zig

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
814814

815815
/////////////// 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+
817825
cases.add_2("Parameterless function prototypes",
818826
\\void a() {}
819827
\\void b(void) {}
@@ -1024,7 +1032,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
10241032
\\pub inline fn glClearUnion(arg_2: GLbitfield) void {
10251033
\\ return glProcs.gl.Clear.?(arg_2);
10261034
\\}
1027-
,
1035+
,
10281036
\\pub const OpenGLProcs = union_OpenGLProcs;
10291037
});
10301038

@@ -2166,7 +2174,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
21662174
});
21672175

21682176
cases.add_2("macro cast",
2169-
\\#define FOO(bar) baz((void *)(baz))
2177+
\\#define FOO(bar) baz((void *)(baz))
21702178
, &[_][]const u8{
21712179
\\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))) {
21722180
\\ 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));

0 commit comments

Comments
 (0)