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-7156] Synthesized instance methods result in vtable-related crashes #49704

Closed
lorentey opened this issue Mar 9, 2018 · 6 comments
Closed
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@lorentey
Copy link
Member

lorentey commented Mar 9, 2018

Previous ID SR-7156
Radar None
Original Reporter @lorentey
Type Bug
Status Resolved
Resolution Duplicate

Attachment: Download

Environment

Reproducible on all active swift branches, has been like this since SE-0166 landed in Swift 4.0 in Xcode 9.0.

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

md5: 4d3289965aff0abe24dad7917cc5f140

duplicates:

  • SR-6468 inheriting from class with synthesized Codable implementation creates invalid code

relates to:

  • SR-7090 Crashing with EXC_BAD_ACCESS after decoding Codable subclass

Issue Description:

The compiler is able to synthesize Encodable conformance for certain types, including classes. However, something about the synthesized encode(to: ) method isn't right; it results in vtable lookup corruption when such classes are accessed from another source file:

a.swift:

class Base: Encodable {}

class Derived: Base {
  var derived10: Int { return 10 }
  var derived20: Int { return 20 }
}

main.swift:

let d = Derived()
print("d.derived20 == \(d.derived20)") // Prints 10 (expected: 20)
print("d.derived10 == \(d.derived10)") // crash (expected: 10)

Try:

$ swiftc a.swift main.swift 
$ ./main
d.derived20 == 10
Segmentation fault: 11

Apparently main.swift and a.swift disagree about the existence of the encode method in Derived's vtable, which makes the Derived class unusable.

@lorentey
Copy link
Member Author

lorentey commented Mar 9, 2018

Adding a no-op reference to the generated method in main.swift makes it all work:

$ cat main.swift
let d = Derived()
print("d.derived20 == \(d.derived20)")
print("d.derived10 == \(d.derived10)")
_ = d1.encode(to:)
$ swiftc a.swift main.swift
$ ./main
d.derived20 == 20
d.derived10 == 10

My theory is that the Encodable conformance for Base is not actually derived for the main compilation unit unless something makes use of it.

@belkadan
Copy link
Contributor

belkadan commented Mar 9, 2018

That sounds correct. @slavapestov, you made things validate less here. Any insights?

@slavapestov
Copy link
Member

@belkadan if this has been broken since Swift 4.0 it's not cause by my changes but I will investigate the root cause.

@belkadan
Copy link
Contributor

belkadan commented Mar 9, 2018

…I remember thinking that and then wrote what I wrote anyway. Sorry!

@itaiferber
Copy link
Contributor

This has indeed been around for a while. See SR-7090/38030107 and 35647420/34778050 (the older reports I have of this)

@belkadan
Copy link
Contributor

Consolidating.

@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

4 participants