Skip to content

Re-commit harmless patches that could not have caused the verification failure (since we wouldn't run it). #25711

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions lib/SIL/LinearLifetimeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,11 +486,12 @@ LinearLifetimeError swift::valueHasLinearLifetime(
// have been detected by initializing our consuming uses. So we are done.
if (consumingUses.size() == 1 &&
consumingUses[0].getParent() == value->getParentBlock()) {
// Check if any of our non consuming uses are not in the parent block. We
// flag those as additional use after frees. Any in the same block, we would
// have flagged.
// Check if any of our non consuming uses are not in the parent block and
// are reachable. We flag those as additional use after frees. Any in the
// same block, we would have flagged.
if (llvm::any_of(nonConsumingUses, [&](BranchPropagatedUser user) {
return user.getParent() != value->getParentBlock();
return user.getParent() != value->getParentBlock() &&
!deBlocks.isDeadEnd(user.getParent());
})) {
state.error.handleUseAfterFree([&] {
llvm::errs() << "Function: '" << value->getFunction()->getName()
Expand Down
9 changes: 9 additions & 0 deletions lib/SIL/SILUndef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@
using namespace swift;

static ValueOwnershipKind getOwnershipKindForUndef(SILType type, const SILFunction &f) {
if (type.isAddress()) {
// If we have an address only type and we are supposed to use
// lowered addresses, return Owned. Otherwise addresses are any.
if (type.isAddressOnly(f) && f.getConventions().useLoweredAddresses()) {
return ValueOwnershipKind::Owned;
}
return ValueOwnershipKind::Any;
}

if (type.isTrivial(f))
return ValueOwnershipKind::Any;
return ValueOwnershipKind::Owned;
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Mandatory/MarkUninitializedFixup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ struct MarkUninitializedFixup : SILFunctionTransform {

// Then create the new mark_uninitialized and force all uses of the
// project_box to go through the new mark_uninitialized.
SILBuilder B(std::next(PBI->getIterator()));
SILBuilderWithScope B(&*std::next(PBI->getIterator()));
SILValue Undef = SILUndef::get(PBI->getType(), *PBI->getFunction());
auto *NewMUI =
B.createMarkUninitialized(PBI->getLoc(), Undef, MUI->getKind());
Expand Down
60 changes: 60 additions & 0 deletions test/SIL/ownership-verifier/undef.sil
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// RUN: %target-sil-opt -enable-objc-interop -enable-sil-verify-all=0 -module-name Swift -ownership-dumper -o /dev/null %s | %FileCheck %s

// REQUIRES: asserts

sil_stage raw

import Builtin

class Klass {}

struct MyInt {
var i: Builtin.Int32
}

// Make sure that we handle undef in an appropriate way. Do to special handling
// in SIL around undef, we test this using the ownership dumper for simplicity.

// CHECK-LABEL: *** Dumping Function: 'undef_addresses_have_any_ownership'
// CHECK: Visiting: {{.*}}%0 = mark_uninitialized [var] undef : $*Klass
// CHECK-NEXT: Operand Ownership Map:
// CHECK-NEXT: Op #: 0
// CHECK-NEXT: Ownership Map: -- OperandOwnershipKindMap --
// CHECK-NEXT: unowned: Yes. Liveness: MustBeLive
// CHECK-NEXT: owned: Yes. Liveness: MustBeLive
// CHECK-NEXT: guaranteed: Yes. Liveness: MustBeLive
// CHECK-NEXT: any: Yes. Liveness: MustBeLive
// CHECK: Visiting: {{.*}}%1 = mark_uninitialized [var] undef : $Klass
// CHECK-NEXT: Operand Ownership Map:
// CHECK-NEXT: Op #: 0
// CHECK-NEXT: Ownership Map: -- OperandOwnershipKindMap --
// CHECK-NEXT: unowned: No.
// CHECK-NEXT: owned: Yes. Liveness: MustBeInvalidated
// CHECK-NEXT: guaranteed: No.
// CHECK-NEXT: any: Yes. Liveness: MustBeLive
// CHECK: Visiting: {{.*}}%3 = mark_uninitialized [var] undef : $*Builtin.Int32
// CHECK-NEXT: Operand Ownership Map:
// CHECK-NEXT: Op #: 0
// CHECK-NEXT: Ownership Map: -- OperandOwnershipKindMap --
// CHECK-NEXT: unowned: Yes. Liveness: MustBeLive
// CHECK-NEXT: owned: Yes. Liveness: MustBeLive
// CHECK-NEXT: guaranteed: Yes. Liveness: MustBeLive
// CHECK-NEXT: any: Yes. Liveness: MustBeLive
// CHECK: Visiting: {{.*}}%4 = struct $MyInt (undef : $Builtin.Int32)
// CHECK-NEXT: Operand Ownership Map:
// CHECK-NEXT: Op #: 0
// CHECK-NEXT: Ownership Map: -- OperandOwnershipKindMap --
// CHECK-NEXT: unowned: Yes. Liveness: MustBeLive
// CHECK-NEXT: owned: Yes. Liveness: MustBeLive
// CHECK-NEXT: guaranteed: Yes. Liveness: MustBeLive
// CHECK-NEXT: any: Yes. Liveness: MustBeLive
sil [ossa] @undef_addresses_have_any_ownership : $@convention(thin) () -> () {
bb0:
%0 = mark_uninitialized [var] undef : $*Klass
%1 = mark_uninitialized [var] undef : $Klass
destroy_value %1 : $Klass
%2 = mark_uninitialized [var] undef : $*Builtin.Int32
%3 = struct $MyInt(undef : $Builtin.Int32)
%9999 = tuple()
return %9999 : $()
}
27 changes: 27 additions & 0 deletions test/SIL/ownership-verifier/use_verifier.sil
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ sil @unowned_tuple_user : $@convention(thin) ((Builtin.Int32, Builtin.NativeObje
sil @produce_owned_optional : $@convention(thin) () -> @owned Optional<Builtin.NativeObject>
sil @guaranteed_nativeobject_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()

class UnsafeUnownedFieldKlass {
unowned(safe) var x: @sil_unowned Builtin.NativeObject
}

////////////////
// Test Cases //
////////////////
Expand Down Expand Up @@ -1156,3 +1160,26 @@ bb0:
%9999 = tuple()
return %9999 : $()
}

// Make sure that we do not false positive due to borrow users of %12 in an
// unreachable block.
sil [ossa] @test_unreachable_users : $@convention(method) (@guaranteed UnsafeUnownedFieldKlass) -> () {
bb0(%0 : @guaranteed $UnsafeUnownedFieldKlass):
%3 = ref_element_addr %0 : $UnsafeUnownedFieldKlass, #UnsafeUnownedFieldKlass.x
%4 = load_borrow %3 : $*@sil_unowned Builtin.NativeObject
%5 = copy_unowned_value %4 : $@sil_unowned Builtin.NativeObject
end_borrow %4 : $@sil_unowned Builtin.NativeObject
%12 = begin_borrow %5 : $Builtin.NativeObject
%func = function_ref @guaranteed_nativeobject_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
apply %func(%12) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
end_borrow %12 : $Builtin.NativeObject
destroy_value %5 : $Builtin.NativeObject
%36 = tuple ()
return %36 : $()

bb1:
%func2 = function_ref @guaranteed_nativeobject_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
apply %func2(%12) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
unreachable
}