Swift compiler crashes during Combine SIL Instructions via Peephole Optimization

Originator:spaus
Number:rdar://34162269 Date Originated:30 August 2017
Status:Open Resolved:
Product:Xcode Product Version:9.0 Beta 6 (9M214v)
Classification:Bug Reproducible:Yes
 
Summary:
The code in the attached project reliably causes the swift compiler to crash (segmentation fault 11) in either Swift version
 mode (3.2 or 4.0) when the project is built in the Release configuration (or archived).
 
 This only happens for the arm64 architecture.
 
 The compiler does not crash if the project is built in Debug mode.
 
 It does not matter if the delegate class responds to the selector in question, the compiler crashes anyway.  You can
 uncomment out the function declarations of the crash(_:foo:) method in BazTaskDelegate and Bar and the crash will
 still occur.
 
 The error reported is:
 
 1.    While running pass #1095 SILFunctionTransform ""Combine SIL Instructions via Peephole Optimization"" on SILFunction "@_T013CompilerCrash0bA0C9subscriptAA3BarCSgAA3FooCcfgTo".
 for 'subscript(_:)' at /Users/spaus/Documents/Xcode Projects/CompilerCrash/CompilerCrash/CrashCompiler.swift:48:5

There appear to be three aspects of the code that must exist for this crash to occur:
1. The class must declare a subscript operator,
2. The class must use the subscript operator on itself within one of it's own methods
3. The method implementation must also ask the result of the subscript operator if it responds to a method of the same signature as the calling method.

Steps to Reproduce:
Compile the following code in Release mode with the Xcode 9.0 Beta 6 Swift compiler, in either Swift 3.2 or Swift 4.0 compatibility mode:

import Foundation

protocol BazDelegate : NSObjectProtocol {}
protocol BazTaskDelegate : BazDelegate {
    //func crash(_ baz: Baz, foo: Foo)
}

class Foo: NSObject {}
class Bar: NSObject {}
extension Bar: BazTaskDelegate {
    //func crash(_ baz: Baz, foo: Foo){}
}
class Baz : NSObject {}

class CrashCompiler: NSObject {
    subscript(foo: Foo) -> Bar? { get { return Bar() } }
    
    func crash(_ baz: Baz, foo: Foo) {
        if let d = self[foo] as BazTaskDelegate? {
            if d.responds(to: #selector(crash(_:foo:))) {}
        }
    }
}

Expected Results:
The expectation is that this code compiles properly, and that swiftc does not crash.  This code compiles correctly under the Xcode 8.3.3 Swift compiler.

Observed Results:
swiftc crashes with the following output:

The error reported is:
 
 1.    While running pass #1095 SILFunctionTransform ""Combine SIL Instructions via Peephole Optimization"" on SILFunction "@_T013CompilerCrash0bA0C9subscriptAA3BarCSgAA3FooCcfgTo".
 for 'subscript(_:)' at /Users/spaus/Documents/Xcode Projects/CompilerCrash/CompilerCrash/CrashCompiler.swift:48:5

 The stack trace produced is:
 
 0  swift                    0x000000010413342a PrintStackTraceSignalHandler(void*) + 42
 1  swift                    0x0000000104132866 SignalHandler(int) + 662
 2  libsystem_platform.dylib 0x00007fff8c6c4b3a _sigtramp + 26
 3  libsystem_platform.dylib 0x00007fff5f1ca100 _sigtramp + 3534771680
 4  swift                    0x0000000101455623 void llvm::function_ref<void (swift::CanType, swift::ProtocolConformanceRef)>::callback_fn<swift::SILCombiner::propagateConcreteTypeOfInitExistential(swift::FullApplySite, swift::WitnessMethodInst*)::$_5>(long, swift::CanType, swift::ProtocolConformanceRef) + 291
 5  swift                    0x00000001014547ea swift::SILCombiner::propagateConcreteTypeOfInitExistential(swift::FullApplySite, swift::ProtocolDecl*, llvm::function_ref<void (swift::CanType, swift::ProtocolConformanceRef)>) + 1018
 6  swift                    0x00000001014554fa swift::SILCombiner::propagateConcreteTypeOfInitExistential(swift::FullApplySite, swift::WitnessMethodInst*) + 474
 7  swift                    0x000000010144ad4c swift::SILVisitor<swift::SILCombiner, swift::SILInstruction*>::visit(swift::ValueBase*) + 20940
 8  swift                    0x0000000101445863 swift::SILCombiner::doOneIteration(swift::SILFunction&, unsigned int) + 2131
 9  swift                    0x0000000101452534 (anonymous namespace)::SILCombine::run() + 708
 10 swift                    0x00000001014feba3 swift::SILPassManager::runOneIteration() + 5139
 11 swift                    0x0000000100c23e3b swift::SILPassManager::executePassPipelinePlan(swift::SILPassPipelinePlan const&) + 235
 12 swift                    0x0000000101503ba3 swift::runSILOptimizationPasses(swift::SILModule&) + 3907
 13 swift                    0x0000000100aa7cf3 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 14323
 14 swift                    0x0000000100aa2c94 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 7716
 15 swift                    0x0000000100a57bb8 main + 12248
 16 libdyld.dylib            0x00007fff8c4b5235 start + 1
 Stack dump:

Version:
Xcode Version 9.0 beta 6 (9M214v)
macOS Sierra 10.12.6 (16G29)

Notes:


Configuration:
This does not happen when building with the Xcode Version 8.3.3 (8E3004b) swift compiler.
Comments

Comments

I'm seeing this exact same crash compiler crash with any Optimization Level other than None.

While running pass #200513 SILFunctionTransform ""Combine SIL Instructions via Peephole Optimization"" on SILFunction "@_T013FOCollections21FOTableViewControllerC05tableC010Foundation9IndexPathVSgSo07UITableC0C_AG15willSelectRowAttF". for 'tableView(_:willSelectRowAt:)' at /Users/danielkrofchick/Documents/Figure1/Development/App/FOCollections/FOCollections/FOCollections/UITableView/FOTableViewController+Delegate.swift:181:10

The offending code is similar to the one posted above.

open func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    if let configurator = delegateWithIndexPath(indexPath) {
        if configurator.responds(to: #selector(UITableViewDelegate.tableView(_:willSelectRowAt:))) {
            return configurator.tableView?(tableView, willSelectRowAt: indexPath)
        }
    }

    return indexPath
}

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!