That's a great point. Having the UniqueAddress stored in-line can look like shared mutable state to ASAN.
This returns a pointer to the local variable that holds self
, not the address of the object. The self
local variable is copied by default when it's passed to the method, so it could be the address of a temporary stack slot. Not guaranteed to be unique or stable.
drewster99:
Alternatively -- why is this wrong?:
private struct Container {
static var myKey: Void?
}
//elsewhere
objc_setAssociatedObject(self, &Container.myKey, value)
I don't see any problem with that. In fact it looks like the least-effort workaround for existing code if you don't need a String key.
Thanks for the feedback! I updated the workarounds section to mention the Void?
workaround and changed the property wrapper to a class since in-line storage bothers ASAN:
# Constrain implicit raw pointer conversion to bitwise-copyable values
* Proposal: [SE-NNNN](nnnn-implicit-raw-bitwise-conversion.md)
* Authors: [Andrew Trick](https://github.com/atrick)
* Review Manager: TBD
* Status: **Awaiting review**
* Implementation: [apple/swift#63825](https://github.com/apple/swift/pull/63825)
* Review: [[Pitch] Constrain implicit raw pointer conversion to bitwise-copyable values](https://forums.swift.org/t/pitch-constrain-implicit-raw-pointer-conversion-to-bitwise-copyable-values/63314)
## Introduction
This proposal adds restrictions on implicit casts to raw pointers, allowing them only when the source value is "bitwise copyable". A type is bitwise copyable if copying a value of that type requires nothing more than copying each bit in its representation (i.e. `memcpy`). Bitwise copyable types do not require deinitialization. Notably, bitwise copyable types cannot contain object references. Raw pointers are primarily intended for use with bitwise-copyable types because it is extremely difficult and dangerous to work with raw bytes in the presence of object references.
The implicit raw pointer casts that we want to prohibit happen accidentally, without any source-level indication of unsafety. They nonetheless pose a serious safety and security concern. They are a source of programming mistakes leading to runtime crashes but have no discernable benefit.
## Motivation
Swift supports implicit inout conversion to unsafe pointers, meaning that a mutable variable can be passed `inout` to a function that receives an unsafe pointer to the value. According to the normal rules for pointer conversion, this naturally extends to raw pointers. Raw pointers allow the pointer-taking function to operate directly on the value's bytes.
```swift
This file has been truncated. show original
drewster99
(Andrew Benson)
August 25, 2023, 7:35pm
23
Andrew_Trick:
This returns a pointer to the local variable that holds self
, not the address of the object. The self
local variable is copied by default when it's passed to the method, so it could be the address of a temporary stack slot. Not guaranteed to be unique or stable.
Ok, that makes sense.
So, we could have done something like:
return withUnsafeBytes(of: &_placeholder) {
... which would have worked as expected.
I think I'll stick with the Void?
for simplicity at this point. Thanks!