diff --git a/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp b/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp index a13105b2597af..f3b8cf88144c6 100644 --- a/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp +++ b/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp @@ -71,14 +71,14 @@ TypeSubElementCount::TypeSubElementCount(SILType type, SILModule &mod, type.getFieldType(fieldDecl, mod, context), mod, context); number = numElements; + // If we do not have any elements, just set our size to 1. + if (number == 0) + number = 1; if (type.isValueTypeWithDeinit()) { // 'self' has its own liveness represented as an additional field at the // end of the structure. ++number; } - // If we do not have any elements, just set our size to 1. - if (number == 0) - number = 1; return; } @@ -450,6 +450,9 @@ void TypeTreeLeafTypeRange::constructFilteredProjections( callback(newValue, TypeTreeLeafTypeRange(start, next), NeedsDestroy); start = next; } + if (start == 0) { + ++start; + } if (type.isValueTypeWithDeinit()) { // 'self' has its own liveness ++start; diff --git a/test/SILOptimizer/moveonly_addresschecker_unmaximized.sil b/test/SILOptimizer/moveonly_addresschecker_unmaximized.sil index 81749df26dac2..c103cceb06d5b 100644 --- a/test/SILOptimizer/moveonly_addresschecker_unmaximized.sil +++ b/test/SILOptimizer/moveonly_addresschecker_unmaximized.sil @@ -202,3 +202,36 @@ bb0(%s_addr : $*S): %retval = tuple () return %retval : $() } + +sil @getter : $@convention(thin) (@guaranteed M) -> @owned String +sil @die : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> @owned String) -> Never + +// CHECK-LABEL: sil [ossa] @partial_apply_of_borrow_of_deinitless_empty_struct : {{.*}} { +// CHECK: bb0([[M_IN:%[^,]+]] : +// CHECK: [[STACK:%[^,]+]] = alloc_stack $M +// CHECK: store [[M_IN]] to [init] [[STACK]] +// CHECK: [[ADDR:%[^,]+]] = drop_deinit [[STACK]] +// CHECK: [[MB:%[^,]+]] = load_borrow [[ADDR]] +// CHECK: [[GETTER:%[^,]+]] = function_ref @getter +// CHECK: [[PA:%[^,]+]] = partial_apply [callee_guaranteed] [on_stack] [[GETTER]]([[MB]]) +// CHECK: [[DIE:%[^,]+]] = function_ref @die +// CHECK: apply [[DIE]]([[PA]]) +// CHECK: destroy_value [[PA]] +// CHECK: end_borrow [[MB]] +// CHECK: unreachable +// CHECK-LABEL: } // end sil function 'partial_apply_of_borrow_of_deinitless_empty_struct' +sil [ossa] @partial_apply_of_borrow_of_deinitless_empty_struct : $@convention(method) (@owned M) -> () { +bb0(%m_in : @owned $M): + %stack = alloc_stack $M + %addr1 = mark_unresolved_non_copyable_value [consumable_and_assignable] %stack : $*M + store %m_in to [init] %addr1 : $*M + %nodeinit = drop_deinit %addr1 : $*M + %addr = mark_unresolved_non_copyable_value [no_consume_or_assign] %nodeinit : $*M + %m = load [copy] %addr : $*M + %mb = begin_borrow %m : $M + %getter = function_ref @getter : $@convention(thin) (@guaranteed M) -> @owned String + %pa = partial_apply [callee_guaranteed] [on_stack] %getter(%mb) : $@convention(thin) (@guaranteed M) -> @owned String + %die = function_ref @die : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> @owned String) -> Never + apply %die(%pa) : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> @owned String) -> Never + unreachable +} diff --git a/validation-test/SILOptimizer/gh68328.swift b/validation-test/SILOptimizer/gh68328.swift index 13b8fb136ee8c..b440ae02497b4 100644 --- a/validation-test/SILOptimizer/gh68328.swift +++ b/validation-test/SILOptimizer/gh68328.swift @@ -7,7 +7,7 @@ // REQUIRES: executable_test struct Example: ~Copyable { - private var failureString: String = "Goodbye." + private var failureString: String { "Goodbye." } deinit { fatalError("FATAL ERROR: \(failureString)") } }