> On Nov 9, 2016, at 17:30, Alexis via swift-dev <swift-dev@swift.org> wrote: > > 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.
I agree with all three lines. Good catch. Can we get Andy’s Swift Type Sanitizer online? :-) Jordan
_______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev