-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Propagate Clang function types through SIL #33085
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
Propagate Clang function types through SIL #33085
Conversation
7e449d1
to
f64538e
Compare
This also manifests as us having code like the following, because we are not enforcing the invariant
This is... not great IMO. If I see the |
We should land the refactoring in #33118 first, assuming no one has major objections. |
To give an update here:
|
f64538e
to
76309a9
Compare
Well, we still have merge conflicts. 💩
|
|
76309a9
to
e16ea36
Compare
I wonder why this fails only on Linux. Not seeing a similar issue building SwiftPM on macOS, or with small snippets using higher-order functions on macOS. Incorrect reconstructed type for $sSvSgA3ASbIetCyyd_SgSbIetCyyyd_SgD Original type: (bound_generic_enum_type decl=Swift.(file).Optional (sil_function_type type=@convention(c) (Optional, Optional, Optional<@convention(c) (Optional, Optional) -> Bool>) -> Bool (input=bound_generic_enum_type decl=Swift.(file).Optional (struct_type decl=Swift.(file).UnsafeMutableRawPointer)) (input=bound_generic_enum_type decl=Swift.(file).Optional (struct_type decl=Swift.(file).UnsafeMutableRawPointer)) (input=bound_generic_enum_type decl=Swift.(file).Optional (sil_function_type type=@convention(c) (Optional, Optional) -> Bool (input=bound_generic_enum_type decl=Swift.(file).Optional (struct_type decl=Swift.(file).UnsafeMutableRawPointer)) (input=bound_generic_enum_type decl=Swift.(file).Optional (struct_type decl=Swift.(file).UnsafeMutableRawPointer)) (result=struct_type decl=Swift.(file).Bool) (substitution_map generic_signature=) (substitution_map generic_signature=) clang_type=PointerType 0xb52e540 '_Bool (*)(void *, void *)' `-FunctionProtoType 0xb52e490 '_Bool (void *, void *)' cdecl |-BuiltinType 0x924bb70 '_Bool' |-PointerType 0x924c310 'void *' imported | `-BuiltinType 0x924bb50 'void' `-PointerType 0x924c310 'void *' imported `-BuiltinType 0x924bb50 'void' )) (result=struct_type decl=Swift.(file).Bool) (substitution_map generic_signature=) (substitution_map generic_signature=))) Reconstructed type: (bound_generic_enum_type decl=Swift.(file).Optional (sil_function_type type=@convention(c) (Optional, Optional, Optional<@convention(c) (Optional, Optional) -> Bool>) -> Bool (input=bound_generic_enum_type decl=Swift.(file).Optional (struct_type decl=Swift.(file).UnsafeMutableRawPointer)) (input=bound_generic_enum_type decl=Swift.(file).Optional (struct_type decl=Swift.(file).UnsafeMutableRawPointer)) (input=bound_generic_enum_type decl=Swift.(file).Optional (sil_function_type type=@convention(c) (Optional, Optional) -> Bool (input=bound_generic_enum_type decl=Swift.(file).Optional (struct_type decl=Swift.(file).UnsafeMutableRawPointer)) (input=bound_generic_enum_type decl=Swift.(file).Optional (struct_type decl=Swift.(file).UnsafeMutableRawPointer)) (result=struct_type decl=Swift.(file).Bool) (substitution_map generic_signature=) (substitution_map generic_signature=) clang_type=PointerType 0xb52e540 '_Bool (*)(void *, void *)' `-FunctionProtoType 0xb52e490 '_Bool (void *, void *)' cdecl |-BuiltinType 0x924bb70 '_Bool' |-PointerType 0x924c310 'void *' imported | `-BuiltinType 0x924bb50 'void' `-PointerType 0x924c310 'void *' imported `-BuiltinType 0x924bb50 'void' )) (result=struct_type decl=Swift.(file).Bool) (substitution_map generic_signature=) (substitution_map generic_signature=) clang_type=PointerType 0xb4e82c0 '_Bool (*)(void *, void *, _Bool (*)(void *, void *))' `-FunctionProtoType 0xb4e8210 '_Bool (void *, void *, _Bool (*)(void *, void *))' cdecl |-BuiltinType 0x924bb70 '_Bool' |-PointerType 0x924c310 'void *' imported | `-BuiltinType 0x924bb50 'void' |-PointerType 0x924c310 'void *' imported | `-BuiltinType 0x924bb50 'void' `-PointerType 0xb52e540 '_Bool (*)(void *, void *)' `-FunctionProtoType 0xb52e490 '_Bool (void *, void *)' cdecl |-BuiltinType 0x924bb70 '_Bool' |-PointerType 0x924c310 'void *' imported | `-BuiltinType 0x924bb50 'void' `-PointerType 0x924c310 'void *' imported `-BuiltinType 0x924bb50 'void' )) |
Did manage to reproduce the issue on Linux. The problem is coming up due to https://github.com/apple/swift-package-manager/blob/96b0ff907fdd4d91fcd207f4c49aae4fce1d9ec5/swift-tools-support-core/Sources/TSCUtility/IndexStore.swift#L215-L215 . We end up specializing a dlsym wrapper (!) with the generic parameter having type Not entirely sure what is dropping the Clang type though, haven't been able to create a minimal example with the same type on macOS. 🤔 EDIT: 🤦🏼 GitHub
|
OK, there are at least two issues here.
Fixing those two things leads to crashes elsewhere from the little that I tested, so there's probably a third problem somewhere. Still not entirely clear why we hit this on Linux but not on macOS. 🤷🏼 |
41acabb
to
bf0d615
Compare
******************** TEST 'Swift(iphonesimulator-i386) :: stdlib/Random.swift' FAILED ******************** Script: -- : 'RUN: at line 1'; rm -rf "/Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/validation-test-iphonesimulator-i386/stdlib/Output/Random.swift.tmp" && mkdir -p "/Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/validation-test-iphonesimulator-i386/stdlib/Output/Random.swift.tmp" && xcrun --toolchain default --sdk '/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.0.sdk' /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/bin/swiftc -target i386-apple-ios7.0-simulator -module-cache-path '/Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/swift-test-results/i386-apple-ios7.0-simulator/clang-module-cache' -F '/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks' -toolchain-stdlib-rpath -Xlinker -rpath -Xlinker /usr/lib/swift -swift-version 4 -Xfrontend -ignore-module-source-info -module-cache-path '/Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/swift-test-results/i386-apple-ios7.0-simulator/clang-module-cache' /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/swift/validation-test/stdlib/Random.swift -o /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/validation-test-iphonesimulator-i386/stdlib/Output/Random.swift.tmp/a.out -module-name main -Xfrontend -disable-access-control && codesign -f -s - /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/validation-test-iphonesimulator-i386/stdlib/Output/Random.swift.tmp/a.out && /usr/bin/env DYLD_LIBRARY_PATH='/Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/lib/swift/iphonesimulator' LD_LIBRARY_PATH='/Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/lib/swift/iphonesimulator:' SIMCTL_CHILD_DYLD_LIBRARY_PATH='/Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/lib/swift/iphonesimulator' xcrun --toolchain default --sdk '/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.0.sdk' simctl spawn --standalone 'iPhone 5' /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/validation-test-iphonesimulator-i386/stdlib/Output/Random.swift.tmp/a.out -- Exit Code: 254 |
For 32-bit iOS/watchOS, both The deserialized type |
Reduced test case:
Here, |
Looking at a slightly less complicated example.
In
Looking at We end up creating a
Due to this mismatch, deserialization falls over. |
Why is deserialization falling over? The import mapping is definitely not 1-1; certain unsigned types being imported as Int is the least of the problems there. But I don't know why the type would be inconsistent in different sources. |
Deserialization falls over because, at the moment, the types are expected to match up exactly. It's not clear to me what ought to be done in case of a mismatch here.
Yeah, I'm not saying that's a problem. But we need to maintain a consistent view internally. I think something is off with this part I highlighted earlier:
It's not clear to me why the substituted formal type is |
SIL type lowering definitely needs to be using the Clang type from the original formal type if there is one. |
So I misspoke slightly here. The original formal type somehow ends up being |
OK. I realized my mistake. I was looking at an AbstractionPattern, not an The problem (or at least one of them) was that when we create the SILConstantInfo, the formal and lowered types end up being |
928f0c7
to
1cbdee0
Compare
d488957
to
3db2d21
Compare
@swift-ci please test |
I think this is ready for review @rjmccall.
|
@swift-ci please test source compatibility |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the slow review. Could you make a separate PR that just does the NFC set-up work, like converting various places to use ExtInfoBuilder
or ExtInfo::getThin()
?
This patch includes a large number of changes to make sure that: 1. When ExtInfo values are created, we store a ClangTypeInfo if applicable. 2. We reduce dependence on storing SIL representations in ASTExtInfo values. 3. Reduce places where we sloppily create ASTExtInfo values which should store a Clang type but don't. In certain places, this is unavoidable; see [NOTE: ExtInfo-Clang-type-invariant]. Ideally, we would check that the appropriate SILExtInfo does always store a ClangTypeInfo. However, the presence of the HasClangFunctionTypes option means that we would need to condition that assertion based on a dynamic check. Plumbing the setting down to SILExtInfoBuilder's checkInvariants would be too much work. So we weaken the check for now; we should strengthen it once we "turn on" HasClangFunctionTypes and remove the dynamic feature switch.
3db2d21
to
983399c
Compare
Fixed the bug in @swift-ci test |
@swift-ci test |
Build failed |
Build failed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks good to me.
@swift-ci please test Windows |
@swift-ci test macOS platform |
@swift-ci test Linux platform |
@swift-ci please clean test Windows |
Re-landing the patch from #29691.
There are still some issues that need to be ironed out:
During type lowering, the Clang type is not being computed when we make an[Updated the primary function in type lowering which does the adjustment, but there still seem to be spots which haven't been fixed..] We see an assertion failure in IRGen where the remangling check fails (the original type does not store a Clang type but the demangled type does).@convention(c)
function. As far as I know, this is the only place missing, but I need to investigate more.@convention(c)
functions which have a derivable C type doesn't change).More generally, I feel like the API around
ExtInfo
is a bit problematic; there is no good place to enforce invariants such as ifrep == CFunctionPointer || rep == Block
, then you must have an associated Clang type. The presence of thewith
methods means that you are sometimes forced to create illegal intermediate states when creating newExtInfo
values. I'm wondering if we should refactor it to use some kind of "builder" API where you have anExtInfoBuilder
which represents a WIP state, and then you call afinish : (ExtInfoBuilder) -> ExtInfo
method which checks if the builder is well-formed, before emitting anExtInfo
.