Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-11480] PropertyWrappers: Compiler crashes (trap 6) when used with initial value + default param #53880

Closed
AliSoftware opened this issue Sep 16, 2019 · 7 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software

Comments

@AliSoftware
Copy link
Contributor

Previous ID SR-11480
Radar None
Original Reporter @AliSoftware
Type Bug
Status Resolved
Resolution Duplicate
Environment

Xcode 11 GM Seeds 1 and 2

Apple Swift version 5.1 (swiftlang-1100.0.270.13 clang-1100.0.33.7)
Target: x86_64-apple-darwin18.7.0

Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, CompilerCrash
Assignee None
Priority Medium

md5: a20c59a7b6228e34751ea45aeb774296

duplicates:

  • SR-11062 Compiler crashes when using attribute syntax with a property wrapper

Issue Description:

Given the following Property Wrapper

import Foundation

@propertyWrapper
struct UserDefault<T> {
    let key: String
    let defaultValue: T
    let suite: UserDefaults

    var wrappedValue: T {
        get { suite.object(forKey: key) as? T ?? defaultValue }
        nonmutating set { suite.set(newValue, forKey: key) }
    }

    init(wrappedValue: T, key: String, suite: UserDefaults = .standard) {
        self.suite = .standard
        self.key = key
        self.defaultValue = wrappedValue
    }
}

There are theorically multiple ways to declare and initialise a property annotated with such a wrapper. The first 3 work great, but the last one make the compiler crash:

class User {
    @UserDefault(wrappedValue: "default1", key: "key1", suite: .standard)
    var value1: String

    @UserDefault(wrappedValue: "default2", key: "key2")
    var value2: String

    @UserDefault(key: "key3", suite: .standard)
    var value3: String = "default3"

    @UserDefault(key: "key4") // trap: 6. Commenting out that line to stop crashing
    var value4: String = "default4"
}

When compiling this code with Xcode 11GM, the 4th variant – which takes advantage both of having the = "default4" to be translated into a wrappedValue: "default4" first parameter to the init, and omits the last parameter in hope of using the default value – makes the compiler crash with the following dump:

$ DEVELOPER_DIR=/Applications/Xcode-11GM.app swift Contents.swift 
swift(83722,0x124d8c5c0) malloc: *** error for object 0x7ffedfd769a0: pointer being realloc'd was not allocated
swift(83722,0x124d8c5c0) malloc: *** set a breakpoint in malloc_error_break to debug
Stack dump:
0.  Program arguments: /Applications/Xcode-11GM.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -interpret Contents.swift -enable-objc-interop -sdk /Applications/Xcode-11GM.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -color-diagnostics -module-name Contents 
1.  While emitting IR SIL function "@$s8Contents4UserCACycfc".
 for 'init()' (at Contents.swift:23:7)
0  swift                    0x00000001142cbeb3 PrintStackTraceSignalHandler(void*) + 51
1  swift                    0x00000001142cb686 SignalHandler(int) + 358
2  libsystem_platform.dylib 0x00007fff69a9db5d _sigtramp + 29
3  libsystem_platform.dylib 0x00007ffedfd75598 _sigtramp + 1982691928
4  libsystem_c.dylib        0x00007fff699576a6 abort + 127
5  libsystem_malloc.dylib   0x00007fff69a66077 malloc_vreport + 545
6  libsystem_malloc.dylib   0x00007fff69a65e38 malloc_report + 151
7  libsystem_malloc.dylib   0x00007fff69a629b6 realloc + 313
8  swift                    0x000000010fff182d swift::irgen::SingleScalarTypeInfo<(anonymous namespace)::ClassTypeInfo, swift::irgen::ReferenceTypeInfo>::getSchema(swift::irgen::ExplosionSchema&) const + 157
9  swift                    0x00000001101659be swift::SILInstructionVisitor<(anonymous namespace)::IRGenSILFunction, void>::visit(swift::SILInstruction*) + 35646
10 swift                    0x000000011015a30a swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 9866
11 swift                    0x00000001100096f7 swift::irgen::IRGenerator::emitLazyDefinitions() + 9303
12 swift                    0x0000000110137100 performIRGeneration(swift::IRGenOptions&, swift::ModuleDecl*, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::LLVMContext&, swift::SourceFile*, llvm::GlobalVariable**) + 1344
13 swift                    0x0000000110134809 swift::performIRGeneration(swift::IRGenOptions&, swift::ModuleDecl*, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::LLVMContext&, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, llvm::GlobalVariable**) + 825
14 swift                    0x000000010ff238fb performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 37051
15 swift                    0x000000010ff17034 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 6820
16 swift                    0x000000010fea45a3 main + 1219
17 libdyld.dylib            0x00007fff698b23d5 start + 1
[1]    83722 abort      DEVELOPER_DIR=/Applications/Xcode-11GM.app swift Contents.swift
@AliSoftware
Copy link
Contributor Author

Note that removing the default value for the suite parameter in init and instead adding an overload init without the suite parameter – delegating to the main one and passing a default value – works around the problem:

    init(wrappedValue: T, key: String, suite: UserDefaults) {
        self.suite = suite
        self.key = key
        self.defaultValue = wrappedValue
    }

    init(wrappedValue: T, key: String) {
        self.init(wrappedValue: wrappedValue, key: key, suite: .standard)
    }

Showing that it's definitively linked to something between the wrappedValue: parameter being inserted and the default value being used

@DougGregor
Copy link
Member

Just fixed this a couple of days ago via https://bugs.swift.org/browse/SR-11062

@AliSoftware
Copy link
Contributor Author

@DougGregor Am I testing this right? I downloaded the latest snapshot then tried to compile the same code again and I still see a crash... so wondering if it has really been fixed?

Might be a slightly different one though, not completely sure, because this time (latest toolchain snapshot) it seems to only appear when I init the enclosing type (struct MainUser) – while with the previous toolchain bundled with 11GM2 it was crashing with or without the call to EnclosingType.init. So crash just seems to have shifted further down the line?

 $ cat Contents.swift 
import Foundation


@propertyWrapper
struct UserDefault<T> {
    var key: String
    let defaultValue: T
    let suite: UserDefaults


    var wrappedValue: T {
        get { suite.object(forKey: key) as? T ?? defaultValue }
        nonmutating set { suite.set(newValue, forKey: key) }
    }


    var projectedValue: Self { self }


    init(wrappedValue: T, key: String, suite: UserDefaults = .standard) {
        self.defaultValue = wrappedValue
        self.key = key
        self.suite = suite
    }
}

//extension UserDefault {
//    // Workaround for https://bugs.swift.org/browse/SR-11480
//    init(wrappedValue: T, key: String) {
//        self.init(wrappedValue: wrappedValue, key: key, suite: .standard)
//    }
//}


struct MainUser {
    @UserDefault(key: "username")
    var name: String = "Olivier"
}


_ = MainUser() // The compiler only crashes if we invoke this. Commenting this out doesn't make it crash.

Compiling this above code as it leads to this crasher, very similar to the original one posted in this SR:

$ DEVELOPER_DIR=/Applications/Xcode-11GM2.app xcrun --toolchain /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2019-09-16-a.xctoolchain swift Contents.swift 
swift(38341,0x114ebf5c0) malloc: *** error for object 0x7ffee21b7930: pointer being realloc'd was not allocated
swift(38341,0x114ebf5c0) malloc: *** set a breakpoint in malloc_error_break to debug
Stack dump:
0.  Program arguments: /Applications/Xcode-11GM2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -interpret Contents.swift -enable-objc-interop -sdk /Applications/Xcode-11GM2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -color-diagnostics -module-name Contents 
1.  While emitting IR SIL function "@$s8Contents8MainUserVACycfC".
 for 'init()' (at Contents.swift:30:8)
0  swift                    0x0000000111e8aeb3 PrintStackTraceSignalHandler(void*) + 51
1  swift                    0x0000000111e8a686 SignalHandler(int) + 358
2  libsystem_platform.dylib 0x00007fff69a9db5d _sigtramp + 29
3  libsystem_platform.dylib 0x00007ffee21b6528 _sigtramp + 2020706792
4  libsystem_c.dylib        0x00007fff699576a6 abort + 127
5  libsystem_malloc.dylib   0x00007fff69a66077 malloc_vreport + 545
6  libsystem_malloc.dylib   0x00007fff69a65e38 malloc_report + 151
7  libsystem_malloc.dylib   0x00007fff69a629b6 realloc + 313
8  swift                    0x000000010dbb082d swift::irgen::SingleScalarTypeInfo<(anonymous namespace)::ClassTypeInfo, swift::irgen::ReferenceTypeInfo>::getSchema(swift::irgen::ExplosionSchema&) const + 157
9  swift                    0x000000010dd249be swift::SILInstructionVisitor<(anonymous namespace)::IRGenSILFunction, void>::visit(swift::SILInstruction*) + 35646
10 swift                    0x000000010dd1930a swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 9866
11 swift                    0x000000010dbc86f7 swift::irgen::IRGenerator::emitLazyDefinitions() + 9303
12 swift                    0x000000010dcf6100 performIRGeneration(swift::IRGenOptions&, swift::ModuleDecl*, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::LLVMContext&, swift::SourceFile*, llvm::GlobalVariable**) + 1344
13 swift                    0x000000010dcf3809 swift::performIRGeneration(swift::IRGenOptions&, swift::ModuleDecl*, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::LLVMContext&, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, llvm::GlobalVariable**) + 825
14 swift                    0x000000010dae28fb performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 37051
15 swift                    0x000000010dad6034 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 6820
16 swift                    0x000000010da635a3 main + 1219
17 libdyld.dylib            0x00007fff698b23d5 start + 1
18 libdyld.dylib            0x000000000000000a start + 2524240950
[1]    38341 abort      DEVELOPER_DIR=/Applications/Xcode-11GM2.app xcrun --toolchain  swift 
 

Note that:

  • Commenting out the call to MainUser() prevent the compiler crasher with the snapshot toolchain

  • Keeping the MainUser() call but uncommenting my workaround via extension UserDefault prevents the crash in latest toolchain, so that workaround still works like in the original SR

  • A difference with the original crasher tested in the main toolchain bundled with Xcode-11GM2 is that in the original crasher, it crashed even if we didn't call MainUser(). Now with yesterday's snapshot, it stops crashing if we don't call MainUser() but it starts crashing again if we do.

@theblixguy
Copy link
Collaborator

It doesn't crash for me on master. Can you check again if Xcode is using the right toolchain? The program arguments mentions XcodeDefault.xctoolchain.

@AliSoftware
Copy link
Contributor Author

Huh that's a good point, didn't see there that Program arguments mentioned XcodeDefault.xctoolchain here...

@theblixguy Any idea what is wrong in my invocation from the terminal then?

@AliSoftware
Copy link
Contributor Author

Could https://bugs.swift.org/browse/SR-11477 be related btw?

@DougGregor
Copy link
Member

https://bugs.swift.org/browse/SR-11477 is more of a policy issue; having it work properly probably depends on this crasher being fixed, but fixing this crasher won't change the behavior of SR-11477.

The easiest way to test out a toolchain is to select it in Xcode's Xcode menu under "Toolchains"; then a normal build from within Xcode will use that compiler (which you can verify in the build log).

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added the crash Bug: A crash, i.e., an abnormal termination of software label Dec 12, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software
Projects
None yet
Development

No branches or pull requests

4 participants