Skip to content

If a ~Copyable initializer can exit before assigning all properties, the compiler can crash #85377

@scoates

Description

@scoates

Description

This is distilled down from a much larger in-situ example.

It seems that the compiler will crash on an incorrect assertion when a non-Copyable type exits init (either through init? … return nil or init … throws … throw, and without initializing all properties.

In the reproduction below, NoCrashy compiles just fine, but Crashy fails with the attached trace.

Reproduction

struct NoCrashy: ~Copyable {
    let record: Bool
    init?() {
        self.record = true
        guard false else { return nil }
    }
}
struct Crashy: ~Copyable {
    let record: Bool
    init?() {
        guard false else { return nil }
        // also happens if this throws instead of returning nil
        self.record = true
    }
}

Stack dump

Apple Swift version 6.2 (swift-6.2-RELEASE)
Target: arm64-apple-macosx26.0
/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file Crashy.swift -target arm64-apple-macosx26.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -color-diagnostics -Xcc -fcolor-diagnostics -empty-abi-descriptor -no-auto-bridging-header-chaining -module-name Crashy -in-process-plugin-server-path /Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/lib/swift/host/libSwiftInProcPluginServer.dylib -plugin-path /Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/local/lib/swift/host/plugins -target-sdk-version 26.0 -target-sdk-name macosx26.0 -external-plugin-path '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server' -external-plugin-path '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server' -o /var/folders/5l/cnsm2jdn5534t4mvnl739g4c0000gn/T/TemporaryDirectory.YbVkbP/Crashy-1.o
error: compile command failed due to signal 6 (use -v to see invocation)
Assertion failed: (isInitialized()), function finishedInitializationOfDefs, file FieldSensitivePrunedLiveness.h, line 1327.
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.      Program arguments: /Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file Crashy.swift -target arm64-apple-macosx26.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -color-diagnostics -Xcc -fcolor-diagnostics -empty-abi-descriptor -no-auto-bridging-header-chaining -module-name Crashy -in-process-plugin-server-path /Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/lib/swift/host/libSwiftInProcPluginServer.dylib -plugin-path /Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/local/lib/swift/host/plugins -target-sdk-version 26.0 -target-sdk-name macosx26.0 -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -o /var/folders/5l/cnsm2jdn5534t4mvnl739g4c0000gn/T/TemporaryDirectory.YbVkbP/Crashy-1.o
1.      Apple Swift version 6.2 (swift-6.2-RELEASE)
2.      Compiling with effective version 5.10
3.      While evaluating request ExecuteSILPipelineRequest(Run pipelines { Mandatory Diagnostic Passes + Enabling Optimization Passes } on SIL for Crashy)
4.      While running pass #61 SILFunctionTransform "MoveOnlyChecker" on SILFunction "@$s6CrashyAAVABSgycfC".
 for 'init()' (at Crashy.swift:3:5)
 #0 0x00000001085d8f18 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x1059dcf18)
 #1 0x00000001085d7644 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x1059db644)
 #2 0x00000001085d9560 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x1059dd560)
 #3 0x00000001928b6744 (/usr/lib/system/libsystem_platform.dylib+0x1804d6744)
 #4 0x00000001928ac888 (/usr/lib/system/libsystem_pthread.dylib+0x1804cc888)
 #5 0x00000001927b2808 (/usr/lib/system/libsystem_c.dylib+0x1803d2808)
 #6 0x00000001927b1a3c (/usr/lib/system/libsystem_c.dylib+0x1803d1a3c)
 #7 0x000000010861988c (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x105a1d88c)
 #8 0x00000001037b8a94 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100bbca94)
 #9 0x00000001037b06a0 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100bb46a0)
#10 0x00000001037daedc (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100bdeedc)
#11 0x00000001038266bc (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100c2a6bc)
#12 0x00000001038273e0 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100c2b3e0)
#13 0x0000000103829bc8 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100c2dbc8)
#14 0x00000001038245ec (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100c285ec)
#15 0x000000010382456c (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100c2856c)
#16 0x0000000103849dac (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100c4ddac)
#17 0x000000010382b7b8 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100c2f7b8)
#18 0x00000001038247dc (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100c287dc)
#19 0x000000010382cd8c (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100c30d8c)
#20 0x00000001030d1d38 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x1004d5d38)
#21 0x0000000102e90fa4 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100294fa4)
#22 0x0000000102e90604 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100294604)
#23 0x0000000102e9cdc8 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x1002a0dc8)
#24 0x0000000102e923fc (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x1002963fc)
#25 0x0000000102e91bb8 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x100295bb8)
#26 0x0000000102c356b4 (/Users/sean/Library/Developer/Toolchains/swift-6.2-RELEASE.xctoolchain/usr/bin/swift-frontend+0x1000396b4)
#27 0x00000001924edd54

Expected behavior

I expected the compiler to let me exit the initializer without declaring all property values if I'm exiting with nil or a throw. When not ~Copyable, I am allowed to do this.

At the very least I expected the compiler to give me an error, not crash.

Seems the isInitialized assertion in finishedInitializationOfDefs is incomplete.

Environment

❯ swiftly run swiftc --version
Apple Swift version 6.2 (swift-6.2-RELEASE)
Target: arm64-apple-macosx26.0
Build config: +assertions

Additional information

I gave this a quick check on 6.1, and it crashes there, too.

I did a quick containerized check of 6.2 on Linux and it didn't crash:

❯ container run -it -v `pwd`:/mnt --rm swift:6.2-noble bash -c 'cd /mnt; swiftc --version ; rm Crashy ; swiftc Crashy.swift ; ls -l Crashy'
Swift version 6.2 (swift-6.2-RELEASE)
Target: aarch64-unknown-linux-gnu
-rwxr-xr-x 1 root root 74256 Nov  7 02:19 Crashy

Metadata

Metadata

Assignees

Labels

SILbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.crashBug: A crash, i.e., an abnormal termination of softwaremove-onlyFeature → type declarations: Move-only type declarations

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions