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-9698] Compiler crashes in switch with multiple binds and fallthroughs #52138

Closed
swift-ci opened this issue Jan 18, 2019 · 7 comments
Closed
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 SILGen Area → compiler: The SIL generation stage

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-9698
Radar None
Original Reporter stjernegard (JIRA User)
Type Bug
Status Resolved
Resolution Done

Attachment: Download

Environment

Apple Swift version 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1)

Target: x86_64-apple-darwin18.2.0

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

md5: a3f450f10f218d52c27124e8ac2b16b9

is duplicated by:

  • SR-10700 Compiler crash on switch using fallthrough and naming repetition

Issue Description:

A crashing Swift project is attached as a zip file together with the output from swift build. The problematic code looks like this:

switch self {
case let .c1(a, b, c),
     let .c2(a, b, c):
    try container.encode(c, forKey: .c)
    fallthrough

case let .b1(a, b),
     let .b2(a, b):
    try container.encode(b, forKey: .b)
    fallthrough

case let .a1(a),
     let .a2(a):
    try container.encode(a, forKey: .a)
}

Simpler versions of the switch with fewer cases are possible and will work as expected.

@belkadan
Copy link
Contributor

On master:

SIL verification failed: instruction isn't dominated by its operand: properlyDominates(valueI, I)
Verifying instruction:
   %30 = argument of bb3 : $Int                   // user: %42
   (**%65**, %66) = destructure_tuple %64 : $(a: Int, b: Int) // users: %42, %69, %67
->   br bb5(%65 : $Int, %30 : $Int)               // id: %42
In function:
// A.encode(to:)
sil private @$s4test1A33_9F9099C659B8A128A78BAA9A7C0E0368LLO6encode2toys7Encoder_p_tKF : $@convention(method) (@in_guaranteed Encoder, A) -> @error Error {
// %0                                             // users: %7, %2
// %1                                             // users: %12, %3
bb0(%0 : $*Encoder, %1 : $A):
  debug_value_addr %0 : $*Encoder, let, name "encoder", argno 1 // id: %2
  debug_value %1 : $A, let, name "self", argno 2  // id: %3
  debug_value undef : $Error, var, name "$error", argno 3 // id: %4
  %5 = alloc_box ${ var KeyedEncodingContainer<A.CodingKeys> }, var, name "container" // users: %87, %103, %98, %93, %6
  %6 = project_box %5 : ${ var KeyedEncodingContainer<A.CodingKeys> }, 0 // users: %61, %49, %36, %11
  %7 = open_existential_addr immutable_access %0 : $*Encoder to $*@opened("CA5BB9A0-1B42-11E9-8AEE-9A0002AC2BC0") Encoder // users: %11, %11, %10
  %8 = metatype $@thin A.CodingKeys.Type
  %9 = metatype $@thick A.CodingKeys.Type         // user: %11
  %10 = witness_method $@opened("CA5BB9A0-1B42-11E9-8AEE-9A0002AC2BC0") Encoder, #Encoder.container!1 : <Self where Self : Encoder><Key where Key : CodingKey> (Self) -> (Key.Type) -> KeyedEncodingContainer<Key>, %7 : $*@opened("CA5BB9A0-1B42-11E9-8AEE-9A0002AC2BC0") Encoder : $@convention(witness_method: Encoder) <τ_0_0 where τ_0_0 : Encoder><τ_1_0 where τ_1_0 : CodingKey> (@thick τ_1_0.Type, @in_guaranteed τ_0_0) -> @out KeyedEncodingContainer<τ_1_0> // type-defs: %7; user: %11
  %11 = apply %10<@opened("CA5BB9A0-1B42-11E9-8AEE-9A0002AC2BC0") Encoder, A.CodingKeys>(%6, %9, %7) : $@convention(witness_method: Encoder) <τ_0_0 where τ_0_0 : Encoder><τ_1_0 where τ_1_0 : CodingKey> (@thick τ_1_0.Type, @in_guaranteed τ_0_0) -> @out KeyedEncodingContainer<τ_1_0> // type-defs: %7
  switch_enum %1 : $A, case #A.c1!enumelt.1: bb1, case #A.c2!enumelt.1: bb2, case #A.b1!enumelt.1: bb8, case #A.b2!enumelt.1: bb9, case #A.a1!enumelt.1: bb10, case #A.a2!enumelt.1: bb11 // id: %12

// %13                                            // user: %14
bb1(%13 : $(a: Int, b: Int, c: Int)):             // Preds: bb0
  (%14, %15, %16) = destructure_tuple %13 : $(a: Int, b: Int, c: Int) // users: %20, %17, %20, %18, %20, %19
  debug_value %14 : $Int, let, name "a"           // id: %17
  debug_value %15 : $Int, let, name "b"           // id: %18
  debug_value %16 : $Int, let, name "c"           // id: %19
  br bb3(%14 : $Int, %15 : $Int, %16 : $Int)      // id: %20

// %21                                            // user: %22
bb2(%21 : $(a: Int, b: Int, c: Int)):             // Preds: bb0
  (%22, %23, %24) = destructure_tuple %21 : $(a: Int, b: Int, c: Int) // users: %28, %25, %28, %26, %28, %27
  debug_value %22 : $Int, let, name "a"           // id: %25
  debug_value %23 : $Int, let, name "b"           // id: %26
  debug_value %24 : $Int, let, name "c"           // id: %27
  br bb3(%22 : $Int, %23 : $Int, %24 : $Int)      // id: %28

// %30                                            // user: %42
// %31                                            // user: %38
bb3(%29 : $Int, %30 : $Int, %31 : $Int):          // Preds: bb2 bb1
  %32 = metatype $@thin A.CodingKeys.Type
  %33 = enum $A.CodingKeys, #A.CodingKeys.c!enumelt // user: %35
  %34 = alloc_stack $A.CodingKeys                 // users: %41, %38, %92, %35
  store %33 to [trivial] %34 : $*A.CodingKeys     // id: %35
  %36 = begin_access [modify] [unknown] %6 : $*KeyedEncodingContainer<A.CodingKeys> // users: %40, %38, %91
  // function_ref KeyedEncodingContainer.encode(_:forKey:)
  %37 = function_ref @$ss22KeyedEncodingContainerV6encode_6forKeyySi_xtKF : $@convention(method) <τ_0_0 where τ_0_0 : CodingKey> (Int, @in_guaranteed τ_0_0, @inout KeyedEncodingContainer<τ_0_0>) -> @error Error // user: %38
  try_apply %37<A.CodingKeys>(%31, %34, %36) : $@convention(method) <τ_0_0 where τ_0_0 : CodingKey> (Int, @in_guaranteed τ_0_0, @inout KeyedEncodingContainer<τ_0_0>) -> @error Error, normal bb4, error bb13 // id: %38

bb4(%39 : $()):                                   // Preds: bb3
  end_access %36 : $*KeyedEncodingContainer<A.CodingKeys> // id: %40
  dealloc_stack %34 : $*A.CodingKeys              // id: %41
  br bb5(%65 : $Int, %30 : $Int)                  // id: %42

// %43                                            // user: %55
// %44                                            // user: %51
bb5(%43 : $Int, %44 : $Int):                      // Preds: bb4 bb9 bb8
  %45 = metatype $@thin A.CodingKeys.Type
  %46 = enum $A.CodingKeys, #A.CodingKeys.b!enumelt // user: %48
  %47 = alloc_stack $A.CodingKeys                 // users: %54, %51, %97, %48
  store %46 to [trivial] %47 : $*A.CodingKeys     // id: %48
  %49 = begin_access [modify] [unknown] %6 : $*KeyedEncodingContainer<A.CodingKeys> // users: %53, %51, %96
  // function_ref KeyedEncodingContainer.encode(_:forKey:)
  %50 = function_ref @$ss22KeyedEncodingContainerV6encode_6forKeyySi_xtKF : $@convention(method) <τ_0_0 where τ_0_0 : CodingKey> (Int, @in_guaranteed τ_0_0, @inout KeyedEncodingContainer<τ_0_0>) -> @error Error // user: %51
  try_apply %50<A.CodingKeys>(%44, %47, %49) : $@convention(method) <τ_0_0 where τ_0_0 : CodingKey> (Int, @in_guaranteed τ_0_0, @inout KeyedEncodingContainer<τ_0_0>) -> @error Error, normal bb6, error bb14 // id: %51

bb6(%52 : $()):                                   // Preds: bb5
  end_access %49 : $*KeyedEncodingContainer<A.CodingKeys> // id: %53
  dealloc_stack %47 : $*A.CodingKeys              // id: %54
  br bb7(%43 : $Int)                              // id: %55

// %56                                            // user: %63
bb7(%56 : $Int):                                  // Preds: bb6 bb11 bb10
  %57 = metatype $@thin A.CodingKeys.Type
  %58 = enum $A.CodingKeys, #A.CodingKeys.a!enumelt // user: %60
  %59 = alloc_stack $A.CodingKeys                 // users: %86, %63, %102, %60
  store %58 to [trivial] %59 : $*A.CodingKeys     // id: %60
  %61 = begin_access [modify] [unknown] %6 : $*KeyedEncodingContainer<A.CodingKeys> // users: %85, %63, %101
  // function_ref KeyedEncodingContainer.encode(_:forKey:)
  %62 = function_ref @$ss22KeyedEncodingContainerV6encode_6forKeyySi_xtKF : $@convention(method) <τ_0_0 where τ_0_0 : CodingKey> (Int, @in_guaranteed τ_0_0, @inout KeyedEncodingContainer<τ_0_0>) -> @error Error // user: %63
  try_apply %62<A.CodingKeys>(%56, %59, %61) : $@convention(method) <τ_0_0 where τ_0_0 : CodingKey> (Int, @in_guaranteed τ_0_0, @inout KeyedEncodingContainer<τ_0_0>) -> @error Error, normal bb12, error bb15 // id: %63

// %64                                            // user: %65
bb8(%64 : $(a: Int, b: Int)):                     // Preds: bb0
  (%65, %66) = destructure_tuple %64 : $(a: Int, b: Int) // users: %42, %69, %67, %69, %68
  debug_value %65 : $Int, let, name "a"           // id: %67
  debug_value %66 : $Int, let, name "b"           // id: %68
  br bb5(%65 : $Int, %66 : $Int)                  // id: %69

// %70                                            // user: %71
bb9(%70 : $(a: Int, b: Int)):                     // Preds: bb0
  (%71, %72) = destructure_tuple %70 : $(a: Int, b: Int) // users: %75, %73, %75, %74
  debug_value %71 : $Int, let, name "a"           // id: %73
  debug_value %72 : $Int, let, name "b"           // id: %74
  br bb5(%71 : $Int, %72 : $Int)                  // id: %75

// %76                                            // user: %77
bb10(%76 : $(a: Int)):                            // Preds: bb0
  %77 = destructure_tuple %76 : $(a: Int)         // users: %79, %78
  debug_value %77 : $Int, let, name "a"           // id: %78
  br bb7(%77 : $Int)                              // id: %79

// %80                                            // user: %81
bb11(%80 : $(a: Int)):                            // Preds: bb0
  %81 = destructure_tuple %80 : $(a: Int)         // users: %83, %82
  debug_value %81 : $Int, let, name "a"           // id: %82
  br bb7(%81 : $Int)                              // id: %83

bb12(%84 : $()):                                  // Preds: bb7
  end_access %61 : $*KeyedEncodingContainer<A.CodingKeys> // id: %85
  dealloc_stack %59 : $*A.CodingKeys              // id: %86
  destroy_value %5 : ${ var KeyedEncodingContainer<A.CodingKeys> } // id: %87
  %88 = tuple ()                                  // user: %89
  return %88 : $()                                // id: %89

// %90                                            // user: %94
bb13(%90 : @owned $Error):                        // Preds: bb3
  end_access %36 : $*KeyedEncodingContainer<A.CodingKeys> // id: %91
  dealloc_stack %34 : $*A.CodingKeys              // id: %92
  destroy_value %5 : ${ var KeyedEncodingContainer<A.CodingKeys> } // id: %93
  br bb16(%90 : $Error)                           // id: %94

// %95                                            // user: %99
bb14(%95 : @owned $Error):                        // Preds: bb5
  end_access %49 : $*KeyedEncodingContainer<A.CodingKeys> // id: %96
  dealloc_stack %47 : $*A.CodingKeys              // id: %97
  destroy_value %5 : ${ var KeyedEncodingContainer<A.CodingKeys> } // id: %98
  br bb16(%95 : $Error)                           // id: %99

// %100                                           // user: %104
bb15(%100 : @owned $Error):                       // Preds: bb7
  end_access %61 : $*KeyedEncodingContainer<A.CodingKeys> // id: %101
  dealloc_stack %59 : $*A.CodingKeys              // id: %102
  destroy_value %5 : ${ var KeyedEncodingContainer<A.CodingKeys> } // id: %103
  br bb16(%100 : $Error)                          // id: %104

// %105                                           // user: %106
bb16(%105 : @owned $Error):                       // Preds: bb15 bb14 bb13
  throw %105 : $Error                             // id: %106
} // end sil function '$s4test1A33_9F9099C659B8A128A78BAA9A7C0E0368LLO6encode2toys7Encoder_p_tKF'

Stack dump:
0.  Program arguments: /Volumes/Data/swift-public/build/ninja/swift-macosx-x86_64/bin/swiftc -frontend -c -primary-file /Users/jrose/Downloads/test-9/Sources/test/main.swift -emit-module-path /Users/jrose/Downloads/test-9/.build/x86_64-apple-macosx10.10/debug/test.build/main~partial.swiftmodule -emit-module-doc-path /Users/jrose/Downloads/test-9/.build/x86_64-apple-macosx10.10/debug/test.build/main~partial.swiftdoc -emit-dependencies-path /Users/jrose/Downloads/test-9/.build/x86_64-apple-macosx10.10/debug/test.build/main.d -emit-reference-dependencies-path /Users/jrose/Downloads/test-9/.build/x86_64-apple-macosx10.10/debug/test.build/main.swiftdeps -target x86_64-apple-macosx10.10 -enable-objc-interop -sdk /Volumes/XIA/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -I /Users/jrose/Downloads/test-9/.build/x86_64-apple-macosx10.10/debug -F /Volumes/XIA/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -enable-testing -g -module-cache-path /Users/jrose/Downloads/test-9/.build/x86_64-apple-macosx10.10/debug/ModuleCache -swift-version 4.2 -Onone -D SWIFT_PACKAGE -D DEBUG -color-diagnostics -module-name test -o /Users/jrose/Downloads/test-9/.build/x86_64-apple-macosx10.10/debug/test.build/main.swift.o 
1.  While emitting SIL for 'encode(to:)' (at /Users/jrose/Downloads/test-9/Sources/test/main.swift:11:5)
2.  While silgen emitFunction SIL function "@$s4test1A33_9F9099C659B8A128A78BAA9A7C0E0368LLO6encode2toys7Encoder_p_tKF".
 for 'encode(to:)' (at /Users/jrose/Downloads/test-9/Sources/test/main.swift:11:5)
3.  While verifying SIL function "@$s4test1A33_9F9099C659B8A128A78BAA9A7C0E0368LLO6encode2toys7Encoder_p_tKF".
 for 'encode(to:)' (at /Users/jrose/Downloads/test-9/Sources/test/main.swift:11:5)
0  swiftc                   0x000000011068ec58 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 40
1  swiftc                   0x000000011068ded5 llvm::sys::RunSignalHandlers() + 85
2  swiftc                   0x000000011068f262 SignalHandler(int) + 258
3  libsystem_platform.dylib 0x00007fff74b96b5d _sigtramp + 29
4  libsystem_platform.dylib 0x00000001140d8ac7 _sigtramp + 2673090439
5  libsystem_c.dylib        0x00007fff74a556a6 abort + 127
6  swiftc                   0x000000010d9076a9 (anonymous namespace)::SILVerifier::_require(bool, llvm::Twine const&, std::__1::function<void ()> const&) + 633
7  swiftc                   0x000000010d91cda2 (anonymous namespace)::SILVerifier::visitSILInstruction(swift::SILInstruction*) + 1874
8  swiftc                   0x000000010d90d1eb swift::SILInstructionVisitor<(anonymous namespace)::SILVerifier, void>::visit(swift::SILInstruction*) + 11019
9  swiftc                   0x000000010d90925c (anonymous namespace)::SILVerifier::visitSILBasicBlock(swift::SILBasicBlock*) + 1196
10 swiftc                   0x000000010d903a07 swift::SILFunction::verify(bool) const + 7095
11 swiftc                   0x000000010d341a1d swift::Lowering::SILGenModule::postEmitFunction(swift::SILDeclRef, swift::SILFunction*) + 205
12 swiftc                   0x000000010d34a47d swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 253
13 swiftc                   0x000000010d341462 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 642
14 swiftc                   0x000000010d429345 (anonymous namespace)::SILGenType::visitFuncDecl(swift::FuncDecl*) + 21
15 swiftc                   0x000000010d426c35 (anonymous namespace)::SILGenType::emitType() + 213
16 swiftc                   0x000000010d426b59 swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 25
17 swiftc                   0x000000010d346886 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*) + 822
18 swiftc                   0x000000010d347846 swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*) + 294
19 swiftc                   0x000000010d347ddc swift::performSILGeneration(swift::FileUnit&, swift::SILOptions&) + 44
20 swiftc                   0x000000010cad0ab9 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 7689
21 swiftc                   0x000000010cacdc42 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2978
22 swiftc                   0x000000010ca7fa5e main + 686
23 libdyld.dylib            0x00007fff749af3ed start + 1

@slavapestov, @gottesmm, something to fix while updating SILGenPattern for ownership?

@gottesmm
Copy link
Member

SILGenPattern was already updated for ownership. It doesn't sound like we regressed here, no?

@belkadan
Copy link
Contributor

Yeah, sorry, I just meant it as a "while you're in the area". (And maybe that's not relevant.)

@belkadan
Copy link
Contributor

@gottesmm, was this fixed by your recent reworking?

@gottesmm
Copy link
Member

It should be fixed... yes.

@gottesmm
Copy link
Member

I just tried with 5.0. Fails with 5.0 with a dominance error. Using the swift-DEVELOPMENT-SNAPSHOT-2019-04-06-a.xctoolchain snapshot, this compiles correctly.

stjernegard (JIRA User) Can you try this with one of the latest master snapshots just to verify on your side? Here is a direct link:

https://swift.org/download/#snapshots

@swift-ci
Copy link
Collaborator Author

Comment by Danni Stjernegård (JIRA)

I can confirm it works correctly on the current development snapshot

@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 SILGen Area → compiler: The SIL generation stage
Projects
None yet
Development

No branches or pull requests

4 participants