swiftlang / swift

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

[SR-12099] Swift compiler crashes when attempting to create a character from null string #54535

Open swift-ci opened 4 years ago

swift-ci commented 4 years ago
Previous ID SR-12099
Radar rdar://problem/58999140
Original Reporter Doug Hill (JIRA User)
Type Bug
Environment Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5) Target: x86_64-apple-darwin18.7.0
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 9b87db2713846f0076a6ed9143cc84a3

Issue Description:

Attempting to create a Character variable with an empty string crashes the Swift compiler.

Steps to reproduce:

Enter the following code into the Swift REPL

var temp = Character("")

Expected Results:

A diagnostic with the error 'Can't form a Character from an empty String', and compiler doesn't crash.

Actual Results:

Fatal error: Can't form a Character from an empty String
2020-01-28 14:29:47.065213-0800 repl_swift[1688:80481] Fatal error: Can't form a Character from an empty String
temp: Character = {
 _str = {
     _guts = {
        _object = {
            _countAndFlagsBits = <extracting data from value failed>
            _object = <extracting data from value failed>
        }
     }
  }
}
Execution interrupted. Enter code to recover and continue.
Enter LLDB commands to investigate (type :help for assistance.)
Process 1688 stopped
* thread #&#8203;1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
 frame #&#8203;0: 0x00007fff725cb483 libswiftCore.dylib`function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded, Arg[2] = Dead, Arg[3] = Dead> of Swift._fatalErrorMessage(_: Swift.StaticString, _: Swift.StaticString, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never + 307
libswiftCore.dylib`function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded, Arg[2] = Dead, Arg[3] = Dead> of Swift._fatalErrorMessage(_: Swift.StaticString, _: Swift.StaticString, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never:
-> 0x7fff725cb483 <+307>: ud2 
 0x7fff725cb485 <+309>: movq %r12, %rdi
 0x7fff725cb488 <+312>: addq $0x10, %rdi
 0x7fff725cb48c <+316>: cmpl $0x80, %r14d
swift-ci commented 4 years ago

Comment by Thomas (JIRA)

Quick look into standard library showed that initialization from string is handled this way.

@inlinable @inline(__always)
  public init(_ s: String) {
    _precondition(!s.isEmpty,
      "Can't form a Character from an empty String")
    _debugPrecondition(s.index(after: s.startIndex) == s.endIndex,
      "Can't form a Character from a String containing more than one extended grapheme cluster")

    if _fastPath(s._guts._object.isPreferredRepresentation) {
      self.init(unchecked: s)
      return
    }
    self.init(unchecked: String._copying(s))
}

I assume it was done to achieve higher performance. That could be more appropriately modeled as failable init. However performance is the goal here.

beccadax commented 4 years ago

@swift-ci create