wickwirew/Runtime

Crash in `typeInfo(of:)` for enum bridged from Objective-C

Closed this issue · 2 comments

ole commented

@wickwirew Thanks a lot for adding #68 so quickly!

This code crashes with EXC_BAD_ACCESS (code=1, address=0x0) after merging #68:

import Foundation
import Runtime

let bridgedEnum = try typeInfo(of: ComparisonResult.self)

Environment: macOS 10.15.4, Swift 5.2 (Xcode 11.4).

I'm not sure if inspecting an enum bridged from C/Objective-C is supposed to work at all. Regardless, it should probably not cause a crash.

The crash occurs in EnumMetadata.cases() in the call to record.pointee.type(genericContext:genericArguments:):

            ...
            return Case(
                name: record.pointee.fieldName(),
                payloadType: record.pointee._mangledTypeName.offset == 0
                    ? nil
                    : record.pointee.type( // Crashes here
                        genericContext: pointer.pointee.typeDescriptor,
                        genericArguments: genericVector
                    )
            )

Inside FieldRecord.type(genericContext:genericArguments:), the crash occurs in swift_getTypeByMangledNameInContext.

Unfortunately appears that the metadata does not contain the cases for objc enums, so it will have to skip it.

Fixed it in #70 . Ended up adding two new properties so we can at least inspect the number of cases and cases with payloads when they are not available.

ole commented

Thanks a lot for the quick fix! I tried it out and confirm that the crash is fixed.

Unfortunately appears that the metadata does not contain the cases for objc enums, so it will have to skip it.

Nevertheless this is very useful. Since bridged enums will never have payload cases, having the number of cases is already useful information. Sure, it would be nice if the metadata contained the case names and their integer values, but I don't think Swift/Clang generate that info.