mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #68110 from atrick/fix-silcombine-moveonly
Fix SILCombine miscompile for discard on non-copyable types
This commit is contained in:
@@ -371,6 +371,18 @@ public:
|
||||
// anything other than the init_existential_addr/open_existential_addr
|
||||
// container.
|
||||
|
||||
// There is no interesting scenario where a non-copyable type should have
|
||||
// its allocation eliminated. A destroy_addr cannot be removed because it
|
||||
// may run the struct-deinit, and the lifetime cannot be shortened. A
|
||||
// copy_addr [take] [init] cannot be replaced by a destroy_addr because the
|
||||
// destination may hold a 'discard'ed value, which is never destroyed. This
|
||||
// analysis assumes memory is deinitialized on all paths, which is not the
|
||||
// case for discarded values. Eventually copyable types may also be
|
||||
// discarded; to support that, we will leave a drop_deinit_addr in place.
|
||||
if (ASI->getType().isPureMoveOnly()) {
|
||||
LegalUsers = false;
|
||||
return;
|
||||
}
|
||||
for (auto *Op : getNonDebugUses(ASI)) {
|
||||
visit(Op->getUser());
|
||||
|
||||
|
||||
@@ -24,6 +24,12 @@ enum MaybeFileDescriptor: ~Copyable {
|
||||
deinit
|
||||
}
|
||||
|
||||
struct Wrapper<T>: ~Copyable {
|
||||
var t: T
|
||||
}
|
||||
|
||||
sil @getWrappedValue : $@convention(thin) <T> (@in_guaranteed Wrapper<T>) -> @out T
|
||||
|
||||
// Test that a release_value is not removed for a struct-with-deinit.
|
||||
// Doing so would forget the deinit.
|
||||
//
|
||||
@@ -71,3 +77,20 @@ bb0:
|
||||
%9 = tuple ()
|
||||
return %9 : $()
|
||||
}
|
||||
|
||||
// Test that a move into a discarded value does not result in a destroy_addr
|
||||
//
|
||||
// CHECK-LABEL: sil @testNoDeinit : $@convention(method) <T> (@in Wrapper<T>) -> @out T {
|
||||
// CHECK-NOT: destroy_addr
|
||||
// CHECK-LABEL: } // end sil function 'testNoDeinit'
|
||||
sil @testNoDeinit : $@convention(method) <T> (@in Wrapper<T>) -> @out T {
|
||||
bb0(%0 : $*T, %1 : $*Wrapper<T>):
|
||||
%2 = function_ref @getWrappedValue : $@convention(thin) <T> (@in_guaranteed Wrapper<T>) -> @out T
|
||||
%3 = apply %2<T>(%0, %1) : $@convention(thin) <τ_0_0> (@in_guaranteed Wrapper<τ_0_0>) -> @out τ_0_0
|
||||
%4 = alloc_stack $Wrapper<T>
|
||||
copy_addr [take] %1 to [init] %4 : $*Wrapper<T>
|
||||
// discard
|
||||
dealloc_stack %4 : $*Wrapper<T>
|
||||
%9 = tuple ()
|
||||
return %9 : $()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user