swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.28k stars 10.33k forks source link

[SR-4056] "Abort Trap: 6" While Type Checking Nil Coalescing Operand #46639

Open swift-ci opened 7 years ago

swift-ci commented 7 years ago
Previous ID SR-4056
Radar rdar://problem/30686926
Original Reporter michael (JIRA User)
Type Bug
Status Reopened
Resolution

Attachment: Download

Environment Xcode 8.3 beta 3 (8W132p) Swift 3.1 Snapshot 2017-02-22 (a)
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, 3.1Regression, CompilerCrash, TypeChecker | |Assignee | @DougGregor | |Priority | Medium | md5: fd7ae34163abcf24d9ccbcd97c1cfdf2

Issue Description:

The following example, which compiles and works correctly in Xcode 8.2 with Swift 3, fails to compile with "Abort trap: 6" in Xcode 8.3 beta 3 (8W132p) and Swift 3.1 Snapshot 2017-02-22 (a):

protocol Vehicle { }

class Car: Vehicle { }

protocol Person {
    var car: Car? { get }
}

class Foo {
    var vehicle: Vehicle?
    var person: Person?

    var computedVehicle: Vehicle? {
        return vehicle ?? person?.car
        // ^ Command failed due to signal: Abort trap: 6
    }
}

Sample project attached. See AbortTrap6.swift.

swift-ci commented 7 years ago

Comment by Michael Liberatore (JIRA)

Several workarounds to make this work in Swift 3.1 include using if / else:

var computedVehicle: Vehicle? {
    if vehicle != nil {
        return vehicle
    } else {
        return person?.car
    }
}

Using if / else with conditional binding:

var computedVehicle: Vehicle? {
    if let vehicle = vehicle {
        return vehicle
    } else {
        return person?.car
    }
}

Casting the right-hand-side to the return type:

var computedVehicle: Vehicle? {
    return vehicle ?? (person?.car as Vehicle?)
}

Making the var on the concrete type non-optional:

protocol Person {
    var car: Car { get }
}

Making type of the var on the concrete type a protocol type:

protocol Person {
    var car: Vehicle? { get }
}
belkadan commented 7 years ago
Assertion failed: (InactiveConstraints.size() == 1 && "supposed to be an orphan!"), function solveRec, file /Volumes/Data/swift-public/swift/lib/Sema/CSSolver.cpp, line 2154.

1.  While type-checking getter for computedVehicle at <stdin>:13:9
2.  While type-checking expression at [<stdin>:14:16 - line:14:35] RangeText="vehicle ?? person?.c"
belkadan commented 7 years ago

@swift-ci create

DougGregor commented 7 years ago

https://github.com/apple/swift/pull/7739

DougGregor commented 7 years ago

Fixed on master, GitHub 3.1 PR: https://github.com/apple/swift/pull/7741

DougGregor commented 7 years ago

... and it's been merged into the 3.1 branch. Thank you for reporting this so quickly! I introduced the crash on Monday.

swift-ci commented 7 years ago

Comment by Michael Liberatore (JIRA)

You’re very welcome![]( And thank you)

swift-ci commented 6 years ago

Comment by Sergey Galezdinov (JIRA)

Caught that on xcode 9.3 (9E145), swift 4.1.
Cannot reproduce this on a separate small snippet, but catching it on a large project. The code looks similar to this

struct SomeData {
    let foo: String
    let bar: String
    let z: String
}
var test: [String: SomeData] = ["foo": SomeData(foo: "mark1", bar: "mark2", z: "mark3")]
var test2: [String: SomeData] = [:]

func process(mark1: String) {

}
func process(mark2: String) {

}
func process(mark3: String) {

}

func handleMarks(_ someparam: String, mark1: String, mark2: String, mark3: String, foo: Bool) {
    let instance: SomeData
    if foo {
        guard let existing = test[someparam] ?? test2[someparam] else { return } // the line that actually cause the issue
        instance = existing
    } else {
        guard let existing = test[someparam] else { return }
        instance = existing
    }
    if instance.foo != mark1 {
        process(mark1: mark1)
    }
    if instance.bar != mark2 {
        process(mark2: mark2)
    }
    if instance.z != mark3 {
        process(mark3: mark3)
    }
}

The weird part of it is that when I comment the last if block - no abort trap error at all

stacktrace:

<unknown>:0: error: fatal error encountered during compilation; please file a bug report with your project and the crash log
<unknown>:0: note: Incomplete scavenging after 2nd pass
0  swift                    0x0000000111dafffa PrintStackTraceSignalHandler(void*) + 42
1  swift                    0x0000000111daf3b6 SignalHandler(int) + 966
2  libsystem_platform.dylib 0x00007fff5afc6f5a _sigtramp + 26
3  libsystem_platform.dylib 0x00007ffee186b828 _sigtramp + 2257209576
4  libsystem_c.dylib        0x00007fff5ad641ae abort + 127
5  swift                    0x000000010e4068e7 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*)::$_0::__invoke(void*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) + 519
6  swift                    0x0000000111d67658 llvm::report_fatal_error(llvm::Twine const&, bool) + 280
7  swift                    0x0000000111d67539 llvm::report_fatal_error(char const*, bool) + 41
8  swift                    0x00000001105ca554 llvm::scavengeFrameVirtualRegs(llvm::MachineFunction&, llvm::RegScavenger&) + 516
9  swift                    0x0000000110581db4 (anonymous namespace)::PEI::runOnMachineFunction(llvm::MachineFunction&) + 9684
10 swift                    0x00000001104d3026 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 134
11 swift                    0x0000000111cd77d1 llvm::FPPassManager::runOnFunction(llvm::Function&) + 449
12 swift                    0x0000000111cd7413 llvm::FPPassManager::runOnModule(llvm::Module&) + 67
13 swift                    0x0000000111ce0dd8 llvm::legacy::PassManager::run(llvm::Module&) + 1112
14 swift                    0x000000010e5b0321 swift::performLLVM(swift::IRGenOptions&, swift::DiagnosticEngine*, llvm::sys::SmartMutex<false>*, llvm::GlobalVariable*, llvm::Module*, llvm::TargetMachine*, swift::version::Version const&, llvm::StringRef, swift::UnifiedStatsReporter*) + 7409
15 swift                    0x000000010e41177d performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 44685
16 swift                    0x000000010e404e64 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 7908
17 swift                    0x000000010e3b98b5 main + 18917
18 libdyld.dylib            0x00007fff5acb8015 start + 1
Stack dump:
0.  Program arguments: /Applications/Xcode-9.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -filelist /var/folders/kh/9rw5rwln3_74r_g69jn93t8h0000gn/T/sources-8ee93e -primary-file /Users/user/projects/Project/Controllers/Protocol/Protocol.swift -target arm64-apple-ios8.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode-9.3.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk -I /Users/user/projects/Project/Build/Products/Debug-iphoneos -F /Users/user/projects/Project/Build/Products/Debug-iphoneos -F /Users/user/projects/Project/Build/Products/Debug-iphoneos/Alamofire -F 

....

1.  Running pass 'Function Pass Manager' on module '/Users/user/projects/Project/Build/Intermediates/Project.build/Debug-iphoneos/Project.build/Objects-normal/arm64/Protocol.o'.
2.  Running pass 'Prologue/Epilogue Insertion & Frame Finalization' on function