| // RUN: %target-swift-frontend -emit-sil %s | %FileCheck %s |
| |
| enum ValueEnum { |
| case a(String) |
| case b |
| case c |
| |
| init() { self = .b } |
| |
| init(a: Double) { |
| self.init() |
| _ = self // okay: self has been initialized by the delegation above |
| self = .c |
| } |
| |
| init(a: Float) { |
| self.init() |
| self.init() // this is now OK |
| } |
| |
| init(e: Bool) { |
| if e { |
| self = ValueEnum() |
| } else { |
| self.init() |
| } |
| } |
| |
| // CHECK-LABEL: sil hidden @$s25definite_init_value_types9ValueEnumO1xACSb_tcfC : $@convention(method) (Bool, @thin ValueEnum.Type) -> @owned ValueEnum |
| // CHECK: bb0(%0 : $Bool, %1 : $@thin ValueEnum.Type): |
| // CHECK-NEXT: [[STATE:%.*]] = alloc_stack $Builtin.Int1 |
| // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ValueEnum |
| // CHECK-NEXT: [[INIT_STATE:%.*]] = integer_literal $Builtin.Int1, 0 |
| // CHECK-NEXT: store [[INIT_STATE]] to [[STATE]] |
| // CHECK: [[BOOL:%.*]] = struct_extract %0 : $Bool, #Bool._value |
| // CHECK-NEXT: cond_br [[BOOL]], bb1, bb2 |
| // CHECK: bb1: |
| // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin ValueEnum.Type |
| // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $ValueEnum, #ValueEnum.b!enumelt |
| // CHECK-NEXT: [[SELF_ACCESS:%.*]] = begin_access [modify] [static] [[SELF_BOX]] |
| // CHECK-NEXT: [[NEW_STATE:%.*]] = integer_literal $Builtin.Int1, -1 |
| // CHECK-NEXT: store [[NEW_STATE]] to [[STATE]] |
| // CHECK-NEXT: store [[NEW_SELF]] to [[SELF_ACCESS]] |
| // CHECK-NEXT: end_access [[SELF_ACCESS]] |
| // CHECK-NEXT: br bb3 |
| // CHECK: bb2: |
| // CHECK-NEXT: br bb3 |
| // CHECK: bb3: |
| // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin ValueEnum.Type |
| // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $ValueEnum, #ValueEnum.c!enumelt |
| // CHECK-NEXT: [[SELF_ACCESS:%.*]] = begin_access [modify] [static] [[SELF_BOX]] |
| // CHECK-NEXT: [[STATE_VALUE:%.*]] = load [[STATE]] |
| // CHECK-NEXT: cond_br [[STATE_VALUE]], bb4, bb5 |
| // CHECK: bb4: |
| // CHECK-NEXT: destroy_addr [[SELF_BOX]] |
| // CHECK-NEXT: br bb6 |
| // CHECK: bb5: |
| // CHECK-NEXT: br bb6 |
| // CHECK: bb6: |
| // CHECK-NEXT: [[NEW_STATE:%.*]] = integer_literal $Builtin.Int1, -1 |
| // CHECK-NEXT: store [[NEW_STATE]] to [[STATE]] |
| // CHECK-NEXT: store [[NEW_SELF]] to [[SELF_ACCESS]] |
| // CHECK-NEXT: end_access [[SELF_ACCESS]] |
| // CHECK-NEXT: retain_value [[NEW_SELF]] |
| // CHECK-NEXT: destroy_addr [[SELF_BOX]] |
| // CHECK-NEXT: dealloc_stack [[SELF_BOX]] |
| // CHECK-NEXT: dealloc_stack [[STATE]] |
| // CHECK-NEXT: return [[NEW_SELF]] |
| init(x: Bool) { |
| if x { |
| self = .b |
| } |
| self = .c |
| } |
| } |
| |
| enum AddressEnum { |
| case a(Any) |
| case b |
| case c |
| |
| init() { self = .b } |
| |
| init(e: Bool) { |
| if e { |
| self = AddressEnum() |
| } else { |
| self.init() |
| } |
| } |
| |
| init(x: Bool) { |
| if x { |
| self = .b |
| } |
| self = .c |
| } |
| } |
| |
| struct EmptyStruct {} |
| |
| struct ValueStruct { |
| var ivar: EmptyStruct |
| |
| init() { ivar = EmptyStruct() } |
| |
| init(a: Float) { |
| self.init() |
| self.init() |
| } |
| |
| init(e: Bool) { |
| if e { |
| self.init() |
| } else { |
| self = ValueStruct() |
| } |
| } |
| } |
| |
| struct AddressStruct { |
| var ivar: EmptyStruct // expected-note {{'self.ivar' not initialized}} |
| var any: Any? |
| |
| init() { ivar = EmptyStruct(); any = nil } |
| |
| init(e: Bool) { |
| if e { |
| self = AddressStruct() |
| } else { |
| self.init() |
| } |
| } |
| } |