mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[embedded] Allow string-interpolating fatalError in Embedded Swift
This commit is contained in:
@@ -275,7 +275,6 @@ public func preconditionFailure(
|
||||
/// - line: The line number to print along with `message`. The default is the
|
||||
/// line number where `fatalError(_:file:line:)` is called.
|
||||
@_transparent
|
||||
@_unavailableInEmbedded
|
||||
#if $Embedded
|
||||
@_disfavoredOverload
|
||||
#endif
|
||||
@@ -283,8 +282,19 @@ public func fatalError(
|
||||
_ message: @autoclosure () -> String = String(),
|
||||
file: StaticString = #file, line: UInt = #line
|
||||
) -> Never {
|
||||
#if !$Embedded
|
||||
_assertionFailure("Fatal error", message(), file: file, line: line,
|
||||
flags: _fatalErrorFlags())
|
||||
#else
|
||||
if _isDebugAssertConfiguration() {
|
||||
_assertionFailure("Fatal error", message(), file: file, line: line,
|
||||
flags: _fatalErrorFlags())
|
||||
} else {
|
||||
Builtin.condfail_message(true._value,
|
||||
StaticString("fatal error").unsafeRawPointer)
|
||||
Builtin.unreachable()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if $Embedded
|
||||
|
||||
@@ -134,15 +134,16 @@ internal func _assertionFailure(
|
||||
#if !$Embedded
|
||||
@inline(never)
|
||||
#else
|
||||
@_disfavoredOverload
|
||||
@inline(__always)
|
||||
#endif
|
||||
@_semantics("programtermination_point")
|
||||
@_unavailableInEmbedded
|
||||
internal func _assertionFailure(
|
||||
_ prefix: StaticString, _ message: String,
|
||||
file: StaticString, line: UInt,
|
||||
flags: UInt32
|
||||
) -> Never {
|
||||
#if !$Embedded
|
||||
prefix.withUTF8Buffer {
|
||||
(prefix) -> Void in
|
||||
var message = message
|
||||
@@ -158,6 +159,14 @@ internal func _assertionFailure(
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if _isDebugAssertConfiguration() {
|
||||
var message = message
|
||||
message.withUTF8 { (messageUTF8) -> Void in
|
||||
_embeddedReportFatalErrorInFile(prefix: prefix, message: messageUTF8, file: file, line: line)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Builtin.int_trap()
|
||||
}
|
||||
|
||||
@@ -63,6 +63,17 @@ public func print(_ object: some CustomStringConvertible, terminator: StaticStri
|
||||
}
|
||||
}
|
||||
|
||||
func print(_ buf: UnsafeBufferPointer<UInt8>, terminator: StaticString = "\n") {
|
||||
for c in buf {
|
||||
putchar(CInt(c))
|
||||
}
|
||||
var p = terminator.utf8Start
|
||||
while p.pointee != 0 {
|
||||
putchar(CInt(p.pointee))
|
||||
p += 1
|
||||
}
|
||||
}
|
||||
|
||||
func printCharacters(_ buf: UnsafeRawBufferPointer) {
|
||||
for unsafe c in unsafe buf {
|
||||
putchar(CInt(c))
|
||||
|
||||
@@ -527,6 +527,7 @@ public func swift_clearSensitive(buf: UnsafeMutableRawPointer, nbytes: Int) {
|
||||
}
|
||||
|
||||
@usableFromInline
|
||||
@inline(never)
|
||||
func _embeddedReportFatalError(prefix: StaticString, message: StaticString) {
|
||||
print(prefix, terminator: "")
|
||||
if message.utf8CodeUnitCount > 0 { print(": ", terminator: "") }
|
||||
@@ -534,6 +535,7 @@ func _embeddedReportFatalError(prefix: StaticString, message: StaticString) {
|
||||
}
|
||||
|
||||
@usableFromInline
|
||||
@inline(never)
|
||||
func _embeddedReportFatalErrorInFile(prefix: StaticString, message: StaticString, file: StaticString, line: UInt) {
|
||||
print(file, terminator: ":")
|
||||
print(line, terminator: ": ")
|
||||
@@ -541,3 +543,13 @@ func _embeddedReportFatalErrorInFile(prefix: StaticString, message: StaticString
|
||||
if message.utf8CodeUnitCount > 0 { print(": ", terminator: "") }
|
||||
print(message)
|
||||
}
|
||||
|
||||
@usableFromInline
|
||||
@inline(never)
|
||||
func _embeddedReportFatalErrorInFile(prefix: StaticString, message: UnsafeBufferPointer<UInt8>, file: StaticString, line: UInt) {
|
||||
print(file, terminator: ":")
|
||||
print(line, terminator: ": ")
|
||||
print(prefix, terminator: "")
|
||||
if message.count > 0 { print(": ", terminator: "") }
|
||||
print(message)
|
||||
}
|
||||
|
||||
33
test/embedded/traps-fatalerror-exec2.swift
Normal file
33
test/embedded/traps-fatalerror-exec2.swift
Normal file
@@ -0,0 +1,33 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-clang -x c -c %S/Inputs/unbuffered-putchar.c -o %t/unbuffered-putchar.o
|
||||
|
||||
// RUN: %target-build-swift -enable-experimental-feature Embedded -wmo -runtime-compatibility-version none %s -Xlinker %t/unbuffered-putchar.o -o %t/a.out
|
||||
// RUN: not --crash %t/a.out 2>&1 | %FileCheck %s --check-prefix=CHECK-MESSAGE
|
||||
|
||||
// RUN: %target-build-swift -enable-experimental-feature Embedded -wmo -runtime-compatibility-version none %s -Xlinker %t/unbuffered-putchar.o -o %t/a.out -O
|
||||
// RUN: not --crash %t/a.out 2>&1 | %FileCheck %s --check-prefix=CHECK-NOMESSAGE
|
||||
|
||||
// RUN: %target-build-swift -enable-experimental-feature Embedded -wmo -runtime-compatibility-version none %s -Xlinker %t/unbuffered-putchar.o -o %t/a.out -Osize
|
||||
// RUN: not --crash %t/a.out 2>&1 | %FileCheck %s --check-prefix=CHECK-NOMESSAGE
|
||||
|
||||
// RUN: %target-build-swift -enable-experimental-feature Embedded -wmo -runtime-compatibility-version none %s -Xlinker %t/unbuffered-putchar.o -o %t/a.out -O -assert-config Debug
|
||||
// RUN: not --crash %t/a.out 2>&1 | %FileCheck %s --check-prefix=CHECK-MESSAGE
|
||||
|
||||
// RUN: %target-build-swift -enable-experimental-feature Embedded -wmo -runtime-compatibility-version none %s -Xlinker %t/unbuffered-putchar.o -o %t/a.out -Osize -assert-config Debug
|
||||
// RUN: not --crash %t/a.out 2>&1 | %FileCheck %s --check-prefix=CHECK-MESSAGE
|
||||
|
||||
// REQUIRES: swift_in_compiler
|
||||
// REQUIRES: executable_test
|
||||
// REQUIRES: optimized_stdlib
|
||||
// REQUIRES: OS=macosx || OS=linux-gnu
|
||||
// REQUIRES: swift_test_mode_optimize_none
|
||||
// REQUIRES: swift_feature_Embedded
|
||||
|
||||
func testWithInterpolation(i: Int) {
|
||||
fatalError("task failed successfully \(i)")
|
||||
// CHECK-MESSAGE: {{.*}}/traps-fatalerror-exec2.swift:[[@LINE-1]]: Fatal error: task failed successfully 42
|
||||
// CHECK-NOMESSAGE-NOT: Fatal error
|
||||
// CHECK-NOMESSAGE-NOT: task failed successfully 42
|
||||
}
|
||||
|
||||
testWithInterpolation(i: 42)
|
||||
@@ -27,3 +27,23 @@ public func test() {
|
||||
// CHECK-NOMESSAGE-NEXT: tail call void @llvm.trap()
|
||||
// CHECK-NOMESSAGE-NEXT: unreachable
|
||||
// CHECK-NOMESSAGE-NEXT: }
|
||||
|
||||
public func testWithInterpolation(i: Int) {
|
||||
fatalError("task failed successfully \(i)")
|
||||
}
|
||||
|
||||
// CHECK-MESSAGE: define {{.*}}void @"$e4main21testWithInterpolation1iySi_tF"(i64 %0){{.*}} {
|
||||
// CHECK-MESSAGE: entry:
|
||||
// CHECK-MESSAGE: task failed successfully
|
||||
// CHECK-MESSAGE: {{.*}}call {{.*}}void @"${{(es17_assertionFailure__|es31_embeddedReportFatalErrorInFile6prefix7message4file4lineys12StaticStringV_SRys5UInt8VGAGSutF)}}
|
||||
// CHECK-MESSAGE-SAME: Fatal error
|
||||
// CHECK-MESSAGE-SAME: traps-fatalerror-ir.swift
|
||||
// CHECK-MESSAGE: unreachable
|
||||
// CHECK-MESSAGE: }
|
||||
|
||||
// CHECK-NOMESSAGE: define {{.*}}void @"$e4main21testWithInterpolation1iySi_tF"(i64 %0){{.*}} {
|
||||
// CHECK-NOMESSAGE-NEXT: entry:
|
||||
// CHECK-NOMESSAGE-NEXT: tail call void asm sideeffect "", "n"(i32 0)
|
||||
// CHECK-NOMESSAGE-NEXT: tail call void @llvm.trap()
|
||||
// CHECK-NOMESSAGE-NEXT: unreachable
|
||||
// CHECK-NOMESSAGE-NEXT: }
|
||||
|
||||
Reference in New Issue
Block a user