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

Reply via email to