Skip to content

[SR-704] EXC_BAD_ACCESS on returning nil from a failable initializer of NSObject subclass #43319

@swift-ci

Description

@swift-ci
Previous ID SR-704
Radar rdar://problem/25300543
Original Reporter vlas (JIRA User)
Type Bug
Status Resolved
Resolution Done

Attachment: Download

Environment

Xcode 7.3 beta 3:
Apple Swift version 2.2 (swiftlang-703.0.6.5 clang-703.0.21)
Target: x86_64-apple-macosx10.9

Also affects Snapshot 2016-02-08:
Apple Swift version 3.0-dev (LLVM a7663bb722, Clang 4ca3c7fa28, Swift 1c2f40e)

Additional Detail from JIRA
Votes 9
Component/s
Labels Bug, RunTimeCrash
Assignee @slavapestov
Priority Medium

md5: dc88259bd369e3e8b2a14b1c97eabe8d

is duplicated by:

  • SR-1097 Failable convenience initializer in extension of objc class crashes

Issue Description:

Returning nil from a failable initializer of an NSObject subclass results in a runtime crash in swift_deallocPartialClassInstance call. This doesn't happen if a class method is used instead of a convenience initializer, or if the class doesn't inherit from NSObject. The issue does not depend on optimization level. This is a regression from Swift 2.1 / Xcode 7.2 where the same setup doesn't crash.

Code example

import Foundation

class MyClass: NSObject {

    let property: String

    required init(value: String) {
        self.property = value

        super.init()
    }

    convenience init?(failableValue: String) {
        if failableValue != "" {
            self.init(value: failableValue)
        } else {
            return nil
        }
    }

    static func instanceWithFailableValue(failableValue: String) -> Self? {
        if failableValue != "" {
            return self.init(value: failableValue)
        } else {
            return nil
        }
    }

}

let goodValue = "Don't crash"
let badValue = ""

// This works correctly
let goodObject = MyClass(failableValue: goodValue)
print(goodObject)

// This also works correctly
let workaround = MyClass.instanceWithFailableValue(badValue)
print(workaround)

// This crashes upon returning from the initializer
let badObject = MyClass(failableValue: badValue)
print(badObject)

Stacktrace

* thread #​1: tid = 0x1792d1, 0x0000000100259f40 DemoProject`swift::Metadata::getClassObject() const, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
  * frame #​0: 0x0000000100259f40 DemoProject`swift::Metadata::getClassObject() const
    frame #​1: 0x000000010025353e DemoProject`swift_deallocPartialClassInstance + 62
    frame #​2: 0x000000010026b9e5 DemoProject`MyClass.init(failableValue="") -> MyClass? + 357 at main.swift:0
    frame #​3: 0x000000010026ba42 DemoProject`MyClass.__allocating_init(failableValue : String) -> MyClass? + 66 at main.swift:0
    frame #​4: 0x000000010026c70b DemoProject`testFailableInitializer() -> () + 603 at main.swift:42
    frame #​5: 0x000000010026b67b DemoProject`main + 75 at main.swift:46
    frame #​6: 0x00007fff8edcb5ad libdyld.dylib`start + 1

Metadata

Metadata

Assignees

Labels

bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.crashBug: A crash, i.e., an abnormal termination of softwarerun-time crashBug → crash: Swift code crashed during execution

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions