Skip to content

[SR-3636] wrong objects retained/autoreleased from NS_RELEASES_ARGUMENT/NS_RETURNS_RETAINED #46221

@mayoff

Description

@mayoff
Previous ID SR-3636
Radar rdar://problem/30066053
Original Reporter @mayoff
Type Bug

Attachment: Download

Environment

Crashes with Xcode 8.2.1 toolchain, and also with Swift development snapshot 2017-01-05 for Xcode.

Additional Detail from JIRA
Votes 2
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: 178de470313241a40fd1800eb932d1b2

Issue Description:

Consider this member of NSKeyedUnarchiverDelegate:

- (nullable id)unarchiver:(NSKeyedUnarchiver *)unarchiver didDecodeObject:(nullable id) NS_RELEASES_ARGUMENT object NS_RETURNS_RETAINED;

It should release or autorelease the object argument, and retain the returned object.

The attached program implements this method in Swift. The attached program crashes; just run swift main.swift.

The compiler generates an objc-compatible unarchiver:didDecodeObject: method to conform to the NSKeyedUnarchiverDelegate method.

The generated objc method wraps the Swift method UnarchiverDelegate.unarchiver (_: NSKeyedUnarchiver, didDecode: Any?) -> Any?. The objc method bridges the incoming (nullable id) object to a Swift Any?, and also bridges the returned Swift Any? to nullable id.

The objc method is supposed to consume a +1 retain count on the incoming object and deliver a +1 retain count on the outgoing object. However, it appears that the generated code does the opposite, because the incoming Placeholder ends up leaked, and the outgoing RealDeal ends up over-released, causing a crash.

The attached program contains two commented-out lines that experimentally verify the above hypothesis. If you uncomment the passRetained line, the program no longer crashes. The RealDeal is correctly deallocated and not over-released. If you also uncomment the autorelease line, the Placeholder is correctly deallocated but not over-released.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itself

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions