<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Just stumbled across this mock NSDictionary implementation in the test suite:<br class=""><br class=""><a href="https://github.com/apple/swift/blob/a1dbe066adf826b27dd8e71234ba7e8ce2b26b73/validation-test/stdlib/Dictionary.swift#L1260-L1306" class="">https://github.com/apple/swift/blob/a1dbe066adf826b27dd8e71234ba7e8ce2b26b73/validation-test/stdlib/Dictionary.swift#L1260-L1306</a><div class=""><br class=""></div><div class="">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<span style="color: rgb(37, 37, 37); font-family: sans-serif; font-size: 14px; widows: 1; background-color: rgb(255, 255, 255);" class="">™</span>. Good learning opportunity!</div><div class=""><br class="">Notable lines:<br class=""><br class=""><br class=""><br class="">&nbsp;&nbsp;struct&nbsp;Keys&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;key0:&nbsp;AnyObject&nbsp;=&nbsp;TestObjCKeyTy(10)<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;key1:&nbsp;AnyObject&nbsp;=&nbsp;TestObjCKeyTy(20)<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;key2:&nbsp;AnyObject&nbsp;=&nbsp;TestObjCKeyTy(30)<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;key3:&nbsp;AnyObject&nbsp;=&nbsp;TestObjCKeyTy(40)<br class="">&nbsp; }<div class=""><br class="">&nbsp;&nbsp;var&nbsp;keys&nbsp;=&nbsp;[&nbsp;Keys() ]<br class=""><br class=""><div class="">…</div><div class=""><br class=""></div><div class=""><div class="">&nbsp; &nbsp; if theState.state == 0 {</div><div class="">&nbsp; &nbsp; &nbsp; theState.state = 1</div><div class="">&nbsp; &nbsp; &nbsp; theState.itemsPtr = AutoreleasingUnsafeMutablePointer(keys._baseAddressIfContiguous)</div><div class="">&nbsp; &nbsp; &nbsp; theState.mutationsPtr = _fastEnumerationStorageMutationsPtr</div><div class="">&nbsp; &nbsp; &nbsp; state.pointee = theState</div><div class="">&nbsp; &nbsp; &nbsp; return 4</div><div class="">&nbsp; &nbsp; }</div></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class="">* Strict aliasing violation; just plain UB.</div><div class=""><br class=""></div><div class="">* 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?</div><div class=""><br class=""></div><div class="">* It could also choose to reorder the fields and insert padding however it pleases.</div></div></body></html>