diff --git a/stdlib/public/core/ArrayBuffer.swift b/stdlib/public/core/ArrayBuffer.swift index a6ab5fa0e94..2f436dc4627 100644 --- a/stdlib/public/core/ArrayBuffer.swift +++ b/stdlib/public/core/ArrayBuffer.swift @@ -307,16 +307,16 @@ extension _ArrayBuffer { /// ≤ index < count` @warn_unused_result internal func _isValidSubscript(index : Int, - hoistedIsNativeBuffer: Bool) -> Bool { - if _fastPath(hoistedIsNativeBuffer) { + wasNativeBuffer: Bool) -> Bool { + if _fastPath(wasNativeBuffer) { // We need this precondition check to ensure memory safety. It ensures // that if due to an inout violation a store of a different representation - // to the array (an NSArray) happened between 'hoistedIsNativeBuffer' was + // to the array (an NSArray) happened between 'wasNativeBuffer' was // obtained and now we still are memory safe. To ensure safety we need to // reload the 'isNative' flag from memory which _isNative will do - - // instead of relying on the value in 'hoistedIsNativeBuffer' which could + // instead of relying on the value in 'wasNativeBuffer' which could // have been invalidated by an intervening store since we obtained - // 'hoistedIsNativeBuffer'. See also the comment of _typeCheck. + // 'wasNativeBuffer'. See also the comment of _typeCheck. if (_isClassOrObjCExistential(Element.self)) { // Only non value elements can have non native storage. _precondition(_isNative, @@ -326,7 +326,7 @@ extension _ArrayBuffer { // Note we call through to the native buffer here as it has a more // optimal implementation than just doing `index < count`. return _native._isValidSubscript(index, - hoistedIsNativeBuffer: hoistedIsNativeBuffer) + wasNativeBuffer: wasNativeBuffer) } // _getElementSlowPath does its own subscript checking. Therefore we just // return `true`. This simplifies the inlined code. @@ -343,17 +343,17 @@ extension _ArrayBuffer { /// ≤ index < count`. @warn_unused_result internal func _isValidSubscript(index : Int, - hoistedIsNativeTypeCheckedBuffer : Bool) + wasNativeTypeCheckedBuffer : Bool) -> Bool { - // This is the same function as _isValidSubscript with hoistedIsNativeBuffer, + // This is the same function as _isValidSubscript with wasNativeBuffer, // except for the _precondition checks. See the comments there. - if _fastPath(hoistedIsNativeTypeCheckedBuffer) { + if _fastPath(wasNativeTypeCheckedBuffer) { if (_isClassOrObjCExistential(Element.self)) { _precondition(_isNativeTypeChecked, "inout rules were violated: the array was overwritten") } return _nativeTypeChecked._isValidSubscript(index, - hoistedIsNativeBuffer: true) + wasNativeBuffer: true) } if (_isClassOrObjCExistential(Element.self)) { _precondition(!_isNativeTypeChecked, @@ -369,8 +369,8 @@ extension _ArrayBuffer { @inline(__always) @warn_unused_result - func getElement(i: Int, hoistedIsNativeTypeCheckedBuffer: Bool) -> Element { - if _fastPath(hoistedIsNativeTypeCheckedBuffer) { + func getElement(i: Int, wasNativeTypeCheckedBuffer: Bool) -> Element { + if _fastPath(wasNativeTypeCheckedBuffer) { return _nativeTypeChecked[i] } return unsafeBitCast(_getElementSlowPath(i), Element.self) @@ -379,12 +379,14 @@ extension _ArrayBuffer { @inline(never) @warn_unused_result func _getElementSlowPath(i: Int) -> AnyObject { - _sanityCheck(_isClassOrObjCExistential(Element.self), "Only single reference elements can be indexed here.") + _sanityCheck( + _isClassOrObjCExistential(Element.self), + "Only single reference elements can be indexed here.") let element: AnyObject if _isNative { // _isValidSubscript does no subscript checking for the slow path. // Therefore we have to do it here. - _precondition(_native._isValidSubscript(i, hoistedIsNativeBuffer: true), + _precondition(_native._isValidSubscript(i, wasNativeBuffer: true), "Array index out of range") element = castToBufferOf(AnyObject.self)._native[i] _precondition( @@ -403,7 +405,7 @@ extension _ArrayBuffer { /// Get or set the value of the ith element. public subscript(i: Int) -> Element { get { - return getElement(i, hoistedIsNativeTypeCheckedBuffer:_isNativeTypeChecked) + return getElement(i, wasNativeTypeCheckedBuffer:_isNativeTypeChecked) } nonmutating set { diff --git a/stdlib/public/core/Arrays.swift.gyb b/stdlib/public/core/Arrays.swift.gyb index 64aa42ce2ca..6725ed837b7 100644 --- a/stdlib/public/core/Arrays.swift.gyb +++ b/stdlib/public/core/Arrays.swift.gyb @@ -211,9 +211,9 @@ public struct ${Self} get { let isNativeTypeChecked = _getArrayPropertyIsNativeTypeChecked() _checkSubscript(index, - hoistedIsNativeTypeCheckedBuffer: isNativeTypeChecked) + wasNativeTypeCheckedBuffer: isNativeTypeChecked) return _getElement(index, - hoistedIsNativeTypeCheckedBuffer: isNativeTypeChecked) + wasNativeTypeCheckedBuffer: isNativeTypeChecked) } // on non-Objective-C, this should just be NativeOwner for all other // cases, including ArraySlice. @@ -221,7 +221,7 @@ public struct ${Self} % Owner = 'NativeOwner' if Self == 'ContiguousArray' else 'Owner' % Result = 'Native' if Self == 'ContiguousArray' else 'Unknown' addressWith${Owner} { - _checkSubscript(index, hoistedIsNativeBuffer: true) + _checkSubscript(index, wasNativeBuffer: true) return (UnsafePointer(_buffer.subscriptBaseAddress + index), Builtin.castTo${Result}Object(_buffer.owner)) } @@ -230,7 +230,7 @@ public struct ${Self} _makeMutableAndUniqueOrPinned() // When an array was made mutable we know it is a backed by a native array // buffer. - _checkSubscript(index, hoistedIsNativeBuffer: true) + _checkSubscript(index, wasNativeBuffer: true) // We are hiding the access to '_buffer.owner' behind a semantic function // to help the compiler hoist uniqueness checks in the case of class or @@ -248,7 +248,7 @@ public struct ${Self} /// ${O1}. public subscript(index: Int) -> Element { addressWithNativeOwner { - _checkSubscript(index, hoistedIsNativeBuffer: true) + _checkSubscript(index, wasNativeBuffer: true) return (UnsafePointer(_buffer.subscriptBaseAddress + index), Builtin.castToNativeObject(_buffer.owner)) } @@ -256,7 +256,7 @@ public struct ${Self} _makeMutableAndUniqueOrPinned() // When an array was made mutable we know it is a backed by a native array // buffer. - _checkSubscript(index, hoistedIsNativeBuffer: true) + _checkSubscript(index, wasNativeBuffer: true) return (_getElementAddress(index), Builtin.tryPin(Builtin.castToNativeObject(_buffer.owner))) } @@ -346,9 +346,9 @@ public struct ${Self} /// ≤ index < count`. @_semantics("array.check_subscript") public // @testable - func _checkSubscript(index: Int, hoistedIsNativeBuffer: Bool) { + func _checkSubscript(index: Int, wasNativeBuffer: Bool) { _precondition(_buffer._isValidSubscript(index, - hoistedIsNativeBuffer: hoistedIsNativeBuffer), + wasNativeBuffer: wasNativeBuffer), "${Self} index out of range") } @@ -357,12 +357,12 @@ public struct ${Self} /// ≤ index < count`. @_semantics("array.check_subscript") public // @testable - func _checkSubscript(index: Int, hoistedIsNativeTypeCheckedBuffer: Bool) { + func _checkSubscript(index: Int, wasNativeTypeCheckedBuffer: Bool) { // Using this specialized version of ArrayBuffer._isValidSubscript (for // the Array subscript-getter) ensures that CSE can eliminate the // _precondition checks in _isValidSubscript in most cases. _precondition(_buffer._isValidSubscript(index, - hoistedIsNativeTypeCheckedBuffer: hoistedIsNativeTypeCheckedBuffer), + wasNativeTypeCheckedBuffer: wasNativeTypeCheckedBuffer), "${Self} index out of range") } %end @@ -378,10 +378,10 @@ public struct ${Self} @_semantics("array.get_element") @inline(__always) public // @testable - func _getElement(index: Int, hoistedIsNativeTypeCheckedBuffer : Bool) + func _getElement(index: Int, wasNativeTypeCheckedBuffer : Bool) -> Element { return _buffer.getElement(index, - hoistedIsNativeTypeCheckedBuffer : hoistedIsNativeTypeCheckedBuffer) + wasNativeTypeCheckedBuffer : wasNativeTypeCheckedBuffer) } @warn_unused_result diff --git a/stdlib/public/core/ContiguousArrayBuffer.swift b/stdlib/public/core/ContiguousArrayBuffer.swift index c61907efdcc..de5efe210dd 100644 --- a/stdlib/public/core/ContiguousArrayBuffer.swift +++ b/stdlib/public/core/ContiguousArrayBuffer.swift @@ -296,10 +296,10 @@ public struct _ContiguousArrayBuffer : _ArrayBufferType { } @warn_unused_result - func getElement(i: Int, hoistedIsNativeTypeCheckedBuffer: Bool) -> Element { + func getElement(i: Int, wasNativeTypeCheckedBuffer: Bool) -> Element { _sanityCheck( _isValidSubscript(i, - hoistedIsNativeBuffer: hoistedIsNativeTypeCheckedBuffer), + wasNativeBuffer: wasNativeTypeCheckedBuffer), "Array index out of range") // If the index is in bounds, we can assume we have storage. return firstElementAddress[i] @@ -308,7 +308,7 @@ public struct _ContiguousArrayBuffer : _ArrayBufferType { /// Get or set the value of the ith element. public subscript(i: Int) -> Element { get { - return getElement(i, hoistedIsNativeTypeCheckedBuffer: true) + return getElement(i, wasNativeTypeCheckedBuffer: true) } nonmutating set { _sanityCheck(i >= 0 && i < count, "Array index out of range") @@ -342,8 +342,10 @@ public struct _ContiguousArrayBuffer : _ArrayBufferType { /// Returns whether the given `index` is valid for subscripting, i.e. `0 /// ≤ index < count`. + /// + /// wasNativeBuffer is used for interface compatibility with ArrayBuffer. @warn_unused_result - func _isValidSubscript(index : Int, hoistedIsNativeBuffer : Bool) -> Bool { + func _isValidSubscript(index : Int, wasNativeBuffer : Bool) -> Bool { /// Instead of returning 0 for no storage, we explicitly check /// for the existance of storage. /// Note that this is better than folding hasStorage in to @@ -356,14 +358,14 @@ public struct _ContiguousArrayBuffer : _ArrayBufferType { /// ≤ index < count`. /// /// For ContiguousArrayBuffer, this is equivalent to the - /// `_isValidSubscript(_:hoistedIsNativeBuffer:)` form, but is necessary + /// `_isValidSubscript(_:wasNativeBuffer:)` form, but is necessary /// for interface parity with `ArrayBuffer`. @inline(__always) @warn_unused_result - func _isValidSubscript(index : Int, hoistedIsNativeTypeCheckedBuffer : Bool) + func _isValidSubscript(index : Int, wasNativeTypeCheckedBuffer : Bool) -> Bool { return _isValidSubscript(index, - hoistedIsNativeTypeCheckedBuffer : hoistedIsNativeTypeCheckedBuffer) + wasNativeTypeCheckedBuffer : wasNativeTypeCheckedBuffer) } /// The number of elements the buffer can store without reallocation. diff --git a/stdlib/public/core/SliceBuffer.swift b/stdlib/public/core/SliceBuffer.swift index 588bc8126e7..1f563b83e91 100644 --- a/stdlib/public/core/SliceBuffer.swift +++ b/stdlib/public/core/SliceBuffer.swift @@ -222,7 +222,7 @@ struct _SliceBuffer : _ArrayBufferType { /// `startIndex ≤ index < endIndex` @warn_unused_result internal func _isValidSubscript( - index : Int, hoistedIsNativeBuffer: Bool + index : Int, wasNativeBuffer: Bool ) -> Bool { return index >= startIndex && index < endIndex } @@ -252,7 +252,7 @@ struct _SliceBuffer : _ArrayBufferType { } @warn_unused_result - func getElement(i: Int, hoistedIsNativeTypeCheckedBuffer: Bool) -> Element { + func getElement(i: Int, wasNativeTypeCheckedBuffer: Bool) -> Element { _sanityCheck(i >= startIndex, "negative slice index is out of range") _sanityCheck(i < endIndex, "slice index out of range") return subscriptBaseAddress[i] @@ -264,7 +264,7 @@ struct _SliceBuffer : _ArrayBufferType { /// `position != endIndex`. public subscript(position: Int) -> Element { get { - return getElement(position, hoistedIsNativeTypeCheckedBuffer: true) + return getElement(position, wasNativeTypeCheckedBuffer: true) } nonmutating set { _sanityCheck(position >= startIndex, "negative slice index is out of range") diff --git a/test/1_stdlib/ArrayTraps.swift.gyb b/test/1_stdlib/ArrayTraps.swift.gyb index 17fda1d8dca..4ff826f6928 100644 --- a/test/1_stdlib/ArrayTraps.swift.gyb +++ b/test/1_stdlib/ArrayTraps.swift.gyb @@ -247,8 +247,8 @@ class ViolateInoutSafeySwitchToObjcBuffer { // loop calls a function that violates inout safety and overrides the array. let isNativeTypeChecked = A._getArrayPropertyIsNativeTypeChecked() for i in 0..