1
- // RUN: %target-swift-frontend -emit-sil -enable-sil-ownership %s -o /dev/null -verify
1
+ // RUN: %target-swift-frontend -emit-sil -enable-sil-ownership %s | %FileCheck %s
2
2
3
- struct EmptyStruct { }
4
-
5
- struct ValueStruct {
6
- var ivar : EmptyStruct // expected-note {{'self.ivar' not initialized}}
7
-
8
- init ( ) { ivar = EmptyStruct ( ) }
3
+ enum ValueEnum {
4
+ case a( String )
5
+ case b
6
+ case c
9
7
8
+ init ( ) { self = . b }
10
9
11
10
init ( a: Double ) {
12
11
self . init ( )
13
- _ = ivar // okay: ivar has been initialized by the delegation above
14
- }
15
-
16
- init ( a: Int ) {
17
- _ = ivar // expected-error {{'self' used before 'self.init' call or assignment to 'self'}}
18
- self . init ( )
12
+ _ = self // okay: self has been initialized by the delegation above
13
+ self = . c
19
14
}
20
15
21
16
init ( a: Float ) {
22
17
self . init ( )
23
18
self . init ( ) // this is now OK
24
19
}
25
20
26
- init ( c: Bool ) {
27
- if c {
28
- return
21
+ init ( e: Bool ) {
22
+ if e {
23
+ self = ValueEnum ( )
24
+ } else {
25
+ self . init ( )
29
26
}
27
+ }
30
28
31
- self . init ( )
32
- } // expected-error {{'self.init' isn't called on all paths before returning from initializer}}
33
-
34
- init ( d: Bool ) {
35
- if d {
36
- return // expected-error {{return from initializer without initializing all stored properties}}
29
+ // CHECK-LABEL: sil hidden @$S25definite_init_value_types9ValueEnumO1xACSb_tcfC : $@convention(method) (Bool, @thin ValueEnum.Type) -> @owned ValueEnum
30
+ // CHECK: bb0(%0 : $Bool, %1 : $@thin ValueEnum.Type):
31
+ // CHECK-NEXT: [[STATE:%.*]] = alloc_stack $Builtin.Int1
32
+ // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ValueEnum
33
+ // CHECK-NEXT: [[INIT_STATE:%.*]] = integer_literal $Builtin.Int1, 0
34
+ // CHECK-NEXT: store [[INIT_STATE]] to [[STATE]]
35
+ // CHECK: [[BOOL:%.*]] = struct_extract %0 : $Bool, #Bool._value
36
+ // CHECK-NEXT: cond_br [[BOOL]], bb1, bb2
37
+ // CHECK: bb1:
38
+ // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin ValueEnum.Type
39
+ // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $ValueEnum, #ValueEnum.b!enumelt
40
+ // CHECK-NEXT: [[SELF_ACCESS:%.*]] = begin_access [modify] [static] [[SELF_BOX]]
41
+ // CHECK-NEXT: [[NEW_STATE:%.*]] = integer_literal $Builtin.Int1, -1
42
+ // CHECK-NEXT: store [[NEW_STATE]] to [[STATE]]
43
+ // CHECK-NEXT: store [[NEW_SELF]] to [[SELF_ACCESS]]
44
+ // CHECK-NEXT: end_access [[SELF_ACCESS]]
45
+ // CHECK-NEXT: br bb2
46
+ // CHECK: bb2:
47
+ // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin ValueEnum.Type
48
+ // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $ValueEnum, #ValueEnum.c!enumelt
49
+ // CHECK-NEXT: [[SELF_ACCESS:%.*]] = begin_access [modify] [static] [[SELF_BOX]]
50
+ // CHECK-NEXT: [[STATE_VALUE:%.*]] = load [[STATE]]
51
+ // CHECK-NEXT: cond_br [[STATE_VALUE]], bb3, bb4
52
+ // CHECK: bb3:
53
+ // CHECK-NEXT: destroy_addr [[SELF_BOX]]
54
+ // CHECK-NEXT: br bb4
55
+ // CHECK: bb4:
56
+ // CHECK-NEXT: [[NEW_STATE:%.*]] = integer_literal $Builtin.Int1, -1
57
+ // CHECK-NEXT: store [[NEW_STATE]] to [[STATE]]
58
+ // CHECK-NEXT: store [[NEW_SELF]] to [[SELF_ACCESS]]
59
+ // CHECK-NEXT: end_access [[SELF_ACCESS]]
60
+ // CHECK-NEXT: retain_value [[NEW_SELF]]
61
+ // CHECK-NEXT: destroy_addr [[SELF_BOX]]
62
+ // CHECK-NEXT: dealloc_stack [[SELF_BOX]]
63
+ // CHECK-NEXT: dealloc_stack [[STATE]]
64
+ // CHECK-NEXT: return [[NEW_SELF]]
65
+ init ( x: Bool ) {
66
+ if x {
67
+ self = . b
37
68
}
38
-
39
- self = ValueStruct ( )
69
+ self = . c
40
70
}
71
+ }
72
+
73
+ enum AddressEnum {
74
+ case a( Any )
75
+ case b
76
+ case c
77
+
78
+ init ( ) { self = . b }
41
79
42
80
init ( e: Bool ) {
43
81
if e {
44
- self . init ( )
82
+ self = AddressEnum ( )
45
83
} else {
46
- self = ValueStruct ( )
84
+ self . init ( )
47
85
}
48
86
}
49
- }
50
87
51
- enum ValueEnum {
52
- case Dinosaur, Train, Truck
88
+ init ( x: Bool ) {
89
+ if x {
90
+ self = . b
91
+ }
92
+ self = . c
93
+ }
94
+ }
53
95
54
- init ( ) { self = . Train }
96
+ struct EmptyStruct { }
55
97
56
- init ( a: Double ) {
57
- self . init ( )
58
- _ = self // okay: self has been initialized by the delegation above
59
- self = . Dinosaur
60
- }
98
+ struct ValueStruct {
99
+ var ivar : EmptyStruct
61
100
62
- init ( a: Int ) {
63
- _ = self // expected-error {{'self' used before 'self.init' call or assignment to 'self'}}
64
- self . init ( )
65
- }
101
+ init ( ) { ivar = EmptyStruct ( ) }
66
102
67
103
init ( a: Float ) {
68
104
self . init ( )
69
- self . init ( ) // this is now OK
70
- }
71
-
72
- init ( c: Bool ) {
73
- if c {
74
- return
75
- }
76
-
77
105
self . init ( )
78
- } // expected-error {{'self.init' isn't called on all paths before returning from initializer}}
79
-
80
- init ( d: Bool ) {
81
- if d {
82
- return
83
- }
84
-
85
- self = ValueEnum ( )
86
- } // expected-error {{'self.init' isn't called on all paths before returning from initializer}}
106
+ }
87
107
88
108
init ( e: Bool ) {
89
109
if e {
90
- self = ValueEnum ( )
91
- } else {
92
110
self . init ( )
111
+ } else {
112
+ self = ValueStruct ( )
93
113
}
94
114
}
95
115
}
@@ -100,22 +120,6 @@ struct AddressStruct {
100
120
101
121
init ( ) { ivar = EmptyStruct ( ) ; any = nil }
102
122
103
- init ( c: Bool ) {
104
- if c {
105
- return
106
- }
107
-
108
- self . init ( )
109
- } // expected-error {{'self.init' isn't called on all paths before returning from initializer}}
110
-
111
- init ( d: Bool ) {
112
- if d {
113
- return
114
- }
115
-
116
- self = AddressStruct ( )
117
- } // expected-error {{return from initializer without initializing all stored properties}}
118
-
119
123
init ( e: Bool ) {
120
124
if e {
121
125
self = AddressStruct ( )
0 commit comments