Just stumbled across this mock NSDictionary implementation in the test suite:
https://github.com/apple/swift/blob/a1dbe066adf826b27dd8e71234ba7e8ce2b26b73/validation-test/stdlib/Dictionary.swift#L1260-L1306
<https://github.com/apple/swift/blob/a1dbe066adf826b27dd8e71234ba7e8ce2b26b73/validation-test/stdlib/Dictionary.swift#L1260-L1306>
It appears to be violating strict aliasing, but I’d just like to verify it with
y’all since it’s a classic example of type punning that the average programmer
expects to work, and will generally work in practice™. Good learning
opportunity!
Notable lines:
struct Keys {
var key0: AnyObject = TestObjCKeyTy(10)
var key1: AnyObject = TestObjCKeyTy(20)
var key2: AnyObject = TestObjCKeyTy(30)
var key3: AnyObject = TestObjCKeyTy(40)
}
var keys = [ Keys() ]
…
if theState.state == 0 {
theState.state = 1
theState.itemsPtr =
AutoreleasingUnsafeMutablePointer(keys._baseAddressIfContiguous)
theState.mutationsPtr = _fastEnumerationStorageMutationsPtr
state.pointee = theState
return 4
}
This appears to be casting a pointer to a struct Keys (containing 4 AnyObjects)
to a pointer to AnyObject, declaring that it’s an array of 4 AnyObjects. So
this is broken in three ways:
* Strict aliasing violation; just plain UB.
* There’s nothing that actually guarantees an instance of Keys is allocated
inline like this, right? The compiler could decide it’s profitable for all
instances of this type to be boxed. Or even random fields to be boxed?
* It could also choose to reorder the fields and insert padding however it
pleases.
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev