Files
swift-mirror/test/SILGen/borrow_from_load_expr.swift
Andrew Trick b56a787c74 SILGen: emit mark_dependence for unsafeAddress
Fixes a correctness issue with unsafe addressors: `unsafeAddress` and
`unsafeMutableAddress`. Previously, the resulting `Unsafe[Mutable]Pointer` did
not depend on `self`, meaning that the compiler is allowed to destroy `self`
before any uses of the pointer. This happens to be valid for
`UnsafePointer.pointee` because, in that case, `self` does not have a lifetime
anyway; the correctness burden was on the programmer to use
`withExtendedLifetime` around all uses of `self`.

Now, unsafe addressors can be used for arbitrary `Self` types.

This also enables lifetime dependence diagnostics when the addressor points to a
`~Escapable` type.

Addressors can now be used as an implementation of borrowed properties.
2024-12-17 09:53:02 -08:00

38 lines
1.5 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend \
// RUN: %s \
// RUN: -Xllvm -sil-print-types -emit-silgen \
// RUN: -debug-diagnostic-names \
// RUN: -I %t \
// RUN: | \
// RUN: %FileCheck %s
public struct FA<T> {
public subscript(_ int: Int) -> T {
// CHECK-LABEL: sil [ossa] @read : {{.*}} {
// function_ref UnsafeMutablePointer.subscript.unsafeAddressor
// CHECK: [[ADDRESSOR:%[^,]+]] = function_ref @$sSpsRi_zrlEyxSicilu
// CHECK: [[POINTER:%[^,]+]] = apply [[ADDRESSOR]]
// CHECK: [[RAW_POINTER:%[^,]+]] = struct_extract [[POINTER]]
// CHECK: [[ADDR:%[^,]+]] = pointer_to_address [[RAW_POINTER]]
// CHECK: [[MD:%.*]] = mark_dependence [unresolved] [[ADDR]] : $*T
// CHECK: [[ACCESS:%[^,]+]] = begin_access [read] [unsafe] [[MD]]
// Verify that no spurious temporary is emitted.
// CHECK-NOT: alloc_stack
// CHECK: yield [[ACCESS]] : $*T, resume [[SUCCESS:bb[0-9]+]], unwind [[FAILURE:bb[0-9]+]]
// CHECK: [[SUCCESS]]:
// CHECK: end_access [[ACCESS]]
// CHECK: [[FAILURE]]:
// CHECK: end_access [[ACCESS]]
// CHECK: unwind
// CHECK-LABEL: } // end sil function 'read'
@_silgen_name("read")
_read {
yield ump[int]
}
}
var ump: UnsafeMutablePointer<T>
}