Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-2586] Final keyword made ObjC based generic type work incorrectly #45191

Closed
swift-ci opened this issue Sep 8, 2016 · 3 comments
Closed
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Sep 8, 2016

Previous ID SR-2586
Radar rdar://problem/28207605
Original Reporter WeZZard (JIRA User)
Type Bug
Status Resolved
Resolution Done

Attachment: Download

Environment

OS X 10.11
iOS 10
Xcode Version 8.0 beta 6 (8S201h)

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, Miscompile
Assignee @slavapestov
Priority Medium

md5: 97f76b90281c05c56d64e940983d184a

is duplicated by:

  • SR-2791 exc_bad_access if I try to inherit generic swift class from NSObject

Issue Description:

A finalized ObjectiveC based generic type with specialized with Swift type will get it work incorrectly. As following code shown,

import UIKit

public enum UIViewMask {
    case cornerRadius(CGFloat)
    case bezierPath(UIBezierPath)
    case cgPath(CoreGraphics.CGPath)
    case image(UIImage)
    case cgImage(CoreGraphics.CGImage)
    case view(UIView)
}

public final class FinalizedObjCAssociated<T>: NSObject {
    public typealias AssociatedValue = T
    public var value: AssociatedValue
    
    public init(_ value: AssociatedValue) {
        self.value = value
        super.init()
    }
}

public class OpenObjCAssociated<T>: NSObject {
    public typealias AssociatedValue = T
    public var value: AssociatedValue
    
    public init(_ value: AssociatedValue) {
        self.value = value
        super.init()
    }
}

// We create a value with 30 corner radius.
let value = UIViewMask.cornerRadius(30)

// And then create an open associated object,
let openAssociated = OpenObjCAssociated(value)

// and a finalized associated object.
let finalizedAssociated = FinalizedObjCAssociated(value)

// The open associated object's value is what we just have set.
print(openAssociated.value)

// But the finalized assocaited object's value is 0.
print(finalizedAssociated.value)

we want the `finalizedAssociated.value` to be `.cornerRadius(30)` just like what `openAssociated.value` is, but it will be `.cornerRadius(0)` eventually.

@belkadan
Copy link
Contributor

belkadan commented Sep 8, 2016

I'm getting 0 for both of them in interpreter mode, too. Something is seriously wrong here.

@slavapestov
Copy link
Member

Yeah, this looks like yet another bug where we mix up generic layout with the ObjC runtime’s sliding. Here’s a minimal test case:

import Foundation

public class C<T>: NSObject {
    final public var value: T
    
    public init(_ value: T) {
        self.value = value
    }
}

let c = C(30)
print(c.value)

The reason it fails specifically when the property is ‘final’ is because we open-code the ref_element_addr there, and we have a concrete type C<Int>. So we use the most specific access pattern we know (constant-direct). But this is wrong because we really ought to use nonconstant-direct. We need to be looking at the original type of the field instead of the substituted type or something.

A workaround is to define a second field of integer type before the final field:

var dummy = 123
var genericField: T

@slavapestov
Copy link
Member

Fixed in #4880

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

3 participants