diff --git a/c2rust-ast-exporter/src/AstExporter.cpp b/c2rust-ast-exporter/src/AstExporter.cpp index abc92f7ae7..70a06fe4b9 100644 --- a/c2rust-ast-exporter/src/AstExporter.cpp +++ b/c2rust-ast-exporter/src/AstExporter.cpp @@ -2625,11 +2625,20 @@ class TranslateASTVisitor final void TypeEncoder::VisitEnumType(const EnumType *T) { auto ed = T->getDecl()->getDefinition(); + + // getDefinition can return NULL if there is only a forward declaration like `enum Foo;` + // Forward declarations of enums are not actually allowed by the C standard, + // but are supported by LLVM and are used in real code, see + // https://github.com/immunant/c2rust/pull/1743#discussion_r3120875668 + if (!ed) { + ed = T->getDecl()->getCanonicalDecl(); + } + encodeType(T, TagEnumType, [T, ed](CborEncoder *local) { cbor_encode_uint(local, uintptr_t(ed)); }); - if (ed != nullptr) astEncoder->TraverseDecl(ed); + astEncoder->TraverseDecl(ed); } void TypeEncoder::VisitRecordType(const RecordType *T) { diff --git a/tests/unit/enums/src/enum_fwd_decl.c b/tests/unit/enums/src/enum_fwd_decl.c index e23e446a2b..4a90052755 100644 --- a/tests/unit/enums/src/enum_fwd_decl.c +++ b/tests/unit/enums/src/enum_fwd_decl.c @@ -10,4 +10,4 @@ struct _Evas_Func }; // dummy item imported by `test_enums.rs` -int foo(int i) { return i;} \ No newline at end of file +struct _Evas_Func foo(struct _Evas_Func i) { return i;}