Skip to content

Commit 6070ffc

Browse files
committed
Fix crash with forward-declared enums
Closes #3754
1 parent a38704d commit 6070ffc

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

src-self-hosted/translate_c.zig

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -725,11 +725,15 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
725725
};
726726

727727
const int_type = ZigClangEnumDecl_getIntegerType(enum_decl);
728+
// The underlying type may be null in case of forward-declared enum
729+
// types, while that's not ISO-C compliant many compilers allow this and
730+
// default to the usual integer type used for all the enums.
728731

729732
// TODO only emit this tag type if the enum tag type is not the default.
730733
// I don't know what the default is, need to figure out how clang is deciding.
731734
// it appears to at least be different across gcc/msvc
732-
if (!isCBuiltinType(int_type, .UInt) and
735+
if (int_type.ptr != null and
736+
!isCBuiltinType(int_type, .UInt) and
733737
!isCBuiltinType(int_type, .Int))
734738
{
735739
_ = try appendToken(c, .LParen, "(");
@@ -1555,8 +1559,7 @@ fn transCCast(
15551559
const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ZigClangQualType_getTypePtr(dst_type));
15561560
return transCCast(rp, scope, loc, ZigClangElaboratedType_getNamedType(elaborated_ty), src_type, expr);
15571561
}
1558-
if (ZigClangQualType_getTypeClass(dst_type) == .Enum)
1559-
{
1562+
if (ZigClangQualType_getTypeClass(dst_type) == .Enum) {
15601563
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
15611564
try builtin_node.params.push(try transQualType(rp, dst_type, loc));
15621565
_ = try appendToken(rp.c, .Comma, ",");

test/translate_c.zig

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

815815
/////////////// Cases that pass for only stage2 ////////////////
816816

817+
cases.add_2("Forward-declared enum",
818+
\\extern enum enum_ty my_enum;
819+
\\enum enum_ty { FOO };
820+
, &[_][]const u8{
821+
\\pub const FOO = 0;
822+
\\pub const enum_enum_ty = extern enum {
823+
\\ FOO,
824+
\\};
825+
\\pub extern var my_enum: enum_enum_ty;
826+
});
827+
817828
cases.add_2("Parameterless function pointers",
818829
\\typedef void (*fn0)();
819830
\\typedef void (*fn1)(char);

0 commit comments

Comments
 (0)