Skip to content

[IRGen] Fix ObjC method signatures for .cxx_construct and .cxx_destruct (not 4.2) #17887

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

Merged
merged 6 commits into from
Jul 14, 2018

Conversation

fay59
Copy link
Contributor

@fay59 fay59 commented Jul 11, 2018

This PR is the same as #17884, except that it is opened targeting master for CI purposes. It uses a different branch because Github won't let you start a second PR with the same branch to the same base, but the head is the same.

Explanation

For aeons past, the Swift compiler has emitted incorrect method signatures for .cxx_construct and .cxx_destruct methods. The signature was hard-coded to "@?", which is the Objective-C type signature for a block. Type signatures and method signatures are different, and this is not a valid method signature.

Scope

Only Swift classes that inherit from NSObject get .cxx_{construct,destruct} methods. It wouldn't be possible to call a Swift .cxx_construct or .cxx_destruct with NSInvocation, although I'm not entirely sure at which point that would fail. This bug is essentially annoying only to people who look at binaries.

Issue

https://bugs.swift.org/browse/SR-8203

Risk

Negligible. We know from experience that you can put garbage in the method signature of .cxx_destruct and it'll go unnoticed for years. In the unlikely, worst-case scenario in which I got it wrong, the garbage will have changed and someone else will step up in 2023 to fix it without anyone else ever noticing that there was a problem.

Testing

Added a test in test/IRGen/objc_methods.swift.

Reviewed By

You?

fay59 added 3 commits July 11, 2018 11:40
"@?" is not a method signature. An acceptable format is "vM@0:N", where
N is the pointer size and M is twice the pointer size. The numeric
values don't matter anymore on Apple platforms because the runtime does
not rely on them (they used to be stack offsets from the base pointer),
but given that the first (self) and second (_cmd) parameters are
pointers, the expected value is easily obtained and it is probably good
style to include it.

Fixes https://bugs.swift.org/browse/SR-8203
Copy link
Contributor

@jrose-apple jrose-apple left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(already reviewed on the previous PR)

@jrose-apple
Copy link
Contributor

@swift-ci Please test

@jrose-apple jrose-apple self-assigned this Jul 11, 2018
@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 917ad05

@fay59
Copy link
Contributor Author

fay59 commented Jul 11, 2018

Sorry, I wasn't careful enough. 6311df3 fixes these test issues.

@fay59
Copy link
Contributor Author

fay59 commented Jul 11, 2018

Side note: I noticed that this stripped whitespace from test/IRGen/objc_bridge.swift. How hard should I try to maintain whitespace in files where it hasn't been stripped?

@jrose-apple
Copy link
Contributor

It's generally frowned upon to edit lines that aren't near what you're changing. git annotate may not be perfect, but interfering with it for no real reason is unfortunate. You just have one line in here, though, so it's not the end of the world.

@jrose-apple
Copy link
Contributor

…whoops, it's more than one line. Yeah, might be better to put that back.

@fay59
Copy link
Contributor Author

fay59 commented Jul 12, 2018

Updated it.

@jrose-apple
Copy link
Contributor

Thank you!

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - a207347

@jrose-apple
Copy link
Contributor

Fun times. On 32-bit platforms, the length of the string is different. You can use a regex match between double braces {{ }} in FileCheck lines, so something like (6|8) is probably fine.

@jrose-apple
Copy link
Contributor

If you want to run these tests locally, you can invoke lit.py on the build/$SUBDIR/swift-macosx-x86_64/test-iphonesimulator-i386/ folder. (See docs/Testing.md.)

@fay59
Copy link
Contributor Author

fay59 commented Jul 12, 2018

Why does it fail only in objc_subclass.swift? Shouldn't objc_methods.swift have the same problem?

// CHECK: [[NO_ARGS_SIGNATURE:@.*]] = private unnamed_addr constant [8 x i8] c"v16@0:8\00"
// ...
// CHECK:   [2 x { i8*, i8*, i8* }] [{
// CHECK:     i8* getelementptr inbounds ([14 x i8], [14 x i8]* @"\01L_selector_data(.cxx_destruct)", i64 0, i64 0),
// CHECK:     i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[NO_ARGS_SIGNATURE]], i64 0, i64 0),
// CHECK:     i8* bitcast (void (%6*, i8*)* @"$S12objc_methods16ObjcDestructibleCfETo" to i8*) }]
// CHECK:   }]

The constant should be private unnamed_addr constant [7 x i8] c"v8@0:4\00" on a 32-bit platform, and that wouldn't match.

@jrose-apple
Copy link
Contributor

It looks like that test is currently limited to x86_64 (see the "REQUIRES: CPU=x86_64" at the top). That's…not wonderful, but changing it to support the other platforms is probably a lot of extra CHECK lines.

The size of the signature for .cxx_construct and .cxx_destruct varies
with the bitness of the target (the signature on 32-bit platforms is one
character shorter than on 64-bit targets), and IRGen/objc_subclass.swift
is the only ObjC test with .cxx_{construct,destruct} methods that runs
on both.
@jrose-apple
Copy link
Contributor

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - a207347

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - a207347

@fay59
Copy link
Contributor Author

fay59 commented Jul 13, 2018

Why did CI try to build a207347 when the HEAD is c625b56?

@jrose-apple
Copy link
Contributor

It's a known issue with the GitHub/Jenkins integration after a force push. We added a check for it that'll auto-restart the build when it happens.

@jrose-apple jrose-apple merged commit f084efb into swiftlang:master Jul 14, 2018
@jrose-apple
Copy link
Contributor

Thanks, Félix!

@fay59
Copy link
Contributor Author

fay59 commented Jul 14, 2018

Thank you for tending to it! Hopefully the next one will go smoother.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants