swiftlang / swift

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

[SR-4532] Crash (EXC_BAD_INSTRUCTION) or endless loop with activated optimization #47109

Open swift-ci opened 7 years ago

swift-ci commented 7 years ago
Previous ID SR-4532
Radar rdar://problem/31535456
Original Reporter papierschiff (JIRA User)
Type Bug

Attachment: Download

Environment - crash: Xcode 8.3 (8E162); macOS 10.12.4 (16E195) - no crash: Xcode 8.2; macOS 10.12.4 (16E195) - endless loop: swift-3.0.2-RELEASE; ubuntu16.04
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, 3.1Regression, OptimizedOnly, RunTimeCrash | |Assignee | None | |Priority | Medium | md5: 259fbacaf2f7da0b69fb8a7b24b2b58f

Issue Description:

The following code crashs, but only with -O or -O -whole-module-optimization. It crashs on linux and macOS
The code works fine without optimization.

_ = Term.gen(TYPE.Correct)
_ = Term.gen(TYPE.Other1)
let mySubClass = SubClass.gen()

class SubClass: Term {
    class func gen () -> SubClass? {
        return Term.gen (TYPE.Correct) as? SubClass
    }
}

enum TYPE: String {
    case Correct        = "Correct"
    case Other1         = "Other1"
    case Other2         = "Other2"

    var enumVar: Term? {
        print("enumVar: \(self)")
        switch self {
        case .Other1:
            print("other1")
            return mySubClass
        case .Other2:
            print("other2")
            return mySubClass
        default: return nil
        }
    }
}

class Term {
    class func gen (_ type: TYPE) -> Term? {
        print("gen: \(type)")
        return type.enumVar
    }
}
gen: Correct
enumVar: Correct
gen: Other1
enumVar: Other1
other1
gen: Correct
enumVar: Correct
Program ended with exit code: 0
gen: Correct
gen: Correct

stacktrace:

Thread 1Queue : com.apple.main-thread (serial)
#​0  0x00000001007f2671 in _dispatch_gate_wait_slow ()
#​1  0x00000001007c86f2 in dispatch_once_f ()
#​2  0x0000000100001e45 in mySubClass.unsafeMutableAddressor [inlined] at /Users/markus/dev/bugs/BugTest/BugTest/Test.swift:11
#​3  0x0000000100001e28 in TYPE.enumVar.getter at /Users/markus/dev/bugs/BugTest/BugTest/Test.swift:29
#​4  0x0000000100002543 in specialized static Term.gen(TYPE) -> Term? at /Users/markus/dev/bugs/BugTest/BugTest/Test.swift:41
#​5  0x0000000100001d30 in static Term.gen(TYPE) -> Term? [inlined] ()
#​6  0x0000000100001d29 in static SubClass.gen() -> SubClass? [inlined] at /Users/markus/dev/bugs/BugTest/BugTest/Test.swift:15
#​7  0x0000000100001d29 in globalinit_33_82D74A4B9A8C83FF240296E04829A753_func0 at /Users/markus/dev/bugs/BugTest/BugTest/Test.swift:11
#​8  0x00000001007c878c in _dispatch_client_callout ()
#​9  0x00000001007c876c in dispatch_once_f ()
#​10 0x0000000100001e45 in mySubClass.unsafeMutableAddressor [inlined] at /Users/markus/dev/bugs/BugTest/BugTest/Test.swift:11
#​11 0x0000000100001e28 in TYPE.enumVar.getter at /Users/markus/dev/bugs/BugTest/BugTest/Test.swift:29
#​12 0x0000000100002543 in specialized static Term.gen(TYPE) -> Term? at /Users/markus/dev/bugs/BugTest/BugTest/Test.swift:41
#​13 0x0000000100001ab3 in static Term.gen(TYPE) -> Term? [inlined] ()
#​14 0x0000000100001aac in main at /Users/markus/dev/bugs/BugTest/BugTest/main.swift:11
#​15 0x00007fff968e8235 in start ()
belkadan commented 7 years ago

@swift-ci create

gottesmm commented 7 years ago

papierschiff (JIRA User) In swift, global initializers run at an unspecified point before the first use of a global initializer. What is happening here is that the optimizer is taking advantage of this behavior to hoist the invocation of the global initializer in enumVar so that it is unconditional. This causes the global initializer for mySubClass to be called re-entrantly which causes dispatch_once to crash. This results in the program being illegal.