diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index bd2c277e2d1..bfa255c6c32 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -1884,6 +1884,11 @@ task array4(type: KonanLocalTest) { source = "runtime/collections/array4.kt" } +task array5(type: KonanLocalTest) { + disabled = (project.testTarget == 'wasm32') // Uses exceptions. + source = "runtime/collections/array5.kt" +} + task typed_array0(type: KonanLocalTest) { goldValue = "OK\n" source = "runtime/collections/typed_array0.kt" @@ -3860,6 +3865,12 @@ interopTest("interop_array_pointers") { source = "interop/basics/arrayPointers.kt" } +standaloneTest("interop_pinning") { + disabled = (project.testTarget == 'wasm32') // Uses exceptions. + source = "interop/basics/pinning.kt" + flags = [ "-tr" ] +} + task interop_convert(type: KonanLocalTest) { source = "codegen/intrinsics/interop_convert.kt" } diff --git a/backend.native/tests/interop/basics/pinning.kt b/backend.native/tests/interop/basics/pinning.kt new file mode 100644 index 00000000000..0bc48331552 --- /dev/null +++ b/backend.native/tests/interop/basics/pinning.kt @@ -0,0 +1,247 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +import kotlin.test.* +import kotlinx.cinterop.* + +@Test fun pinnedByteArrayAddressOf() { + val arr = ByteArray(10) { 0 } + arr.usePinned { + assertEquals(0, it.addressOf(0).pointed.value) + assertEquals(0, it.addressOf(9).pointed.value) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} + +@Test fun pinnedStringAddressOf() { + val str = "0000000000" + str.usePinned { + it.addressOf(0) + it.addressOf(9) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} + +@Test fun pinnedCharArrayAddressOf() { + val arr = CharArray(10) { '0' } + arr.usePinned { + it.addressOf(0) + it.addressOf(9) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} + +@Test fun pinnedShortArrayAddressOf() { + val arr = ShortArray(10) { 0 } + arr.usePinned { + assertEquals(0, it.addressOf(0).pointed.value) + assertEquals(0, it.addressOf(9).pointed.value) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} + +@Test fun pinnedIntArrayAddressOf() { + val arr = IntArray(10) { 0 } + arr.usePinned { + assertEquals(0, it.addressOf(0).pointed.value) + assertEquals(0, it.addressOf(9).pointed.value) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} + +@Test fun pinnedLongArrayAddressOf() { + val arr = LongArray(10) { 0 } + arr.usePinned { + assertEquals(0, it.addressOf(0).pointed.value) + assertEquals(0, it.addressOf(9).pointed.value) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} + +@Test fun pinnedUByteArrayAddressOf() { + val arr = UByteArray(10) { 0U } + arr.usePinned { + assertEquals(0U, it.addressOf(0).pointed.value) + assertEquals(0U, it.addressOf(9).pointed.value) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} + +@Test fun pinnedUShortArrayAddressOf() { + val arr = UShortArray(10) { 0U } + arr.usePinned { + assertEquals(0U, it.addressOf(0).pointed.value) + assertEquals(0U, it.addressOf(9).pointed.value) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} + +@Test fun pinnedUIntArrayAddressOf() { + val arr = UIntArray(10) { 0U } + arr.usePinned { + assertEquals(0U, it.addressOf(0).pointed.value) + assertEquals(0U, it.addressOf(9).pointed.value) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} + +@Test fun pinnedULongArrayAddressOf() { + val arr = ULongArray(10) { 0U } + arr.usePinned { + assertEquals(0U, it.addressOf(0).pointed.value) + assertEquals(0U, it.addressOf(9).pointed.value) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} + +@Test fun pinnedFloatArrayAddressOf() { + val arr = FloatArray(10) { 0.0f } + arr.usePinned { + assertEquals(0.0f, it.addressOf(0).pointed.value) + assertEquals(0.0f, it.addressOf(9).pointed.value) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} + +@Test fun pinnedDoubleArrayAddressOf() { + val arr = DoubleArray(10) { 0.0 } + arr.usePinned { + assertEquals(0.0, it.addressOf(0).pointed.value) + assertEquals(0.0, it.addressOf(9).pointed.value) + assertFailsWith { + it.addressOf(10) + } + assertFailsWith { + it.addressOf(-1) + } + assertFailsWith { + it.addressOf(Int.MAX_VALUE) + } + assertFailsWith { + it.addressOf(Int.MIN_VALUE) + } + } +} diff --git a/backend.native/tests/runtime/collections/array5.kt b/backend.native/tests/runtime/collections/array5.kt new file mode 100644 index 00000000000..8cc1b18fab1 --- /dev/null +++ b/backend.native/tests/runtime/collections/array5.kt @@ -0,0 +1,969 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package runtime.collections.array5 + +import kotlin.test.* +import kotlinx.cinterop.* + +@Test fun arrayGet() { + val arr = Array(10) { 0 } + assertEquals(0, arr[0]) + assertEquals(0, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun arraySet() { + val arr = Array(10) { 0 } + arr[0] = 1 + arr[9] = 1 + assertFailsWith { + arr[10] = 1 + } + assertFailsWith { + arr[-1] = 1 + } + assertFailsWith { + arr[Int.MAX_VALUE] = 1 + } + assertFailsWith { + arr[Int.MIN_VALUE] = 1 + } +} + +@Test fun byteArrayGet() { + val arr = ByteArray(10) { 0 } + assertEquals(0, arr[0]) + assertEquals(0, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun byteArraySet() { + val arr = ByteArray(10) { 0 } + arr[0] = 1 + arr[9] = 1 + assertFailsWith { + arr[10] = 1 + } + assertFailsWith { + arr[-1] = 1 + } + assertFailsWith { + arr[Int.MAX_VALUE] = 1 + } + assertFailsWith { + arr[Int.MIN_VALUE] = 1 + } +} + +@Test fun uByteArrayGet() { + val arr = UByteArray(10) { 0U } + assertEquals(0U, arr[0]) + assertEquals(0U, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun uByteArraySet() { + val arr = UByteArray(10) { 0U } + arr[0] = 1U + arr[9] = 1U + assertFailsWith { + arr[10] = 1U + } + assertFailsWith { + arr[-1] = 1U + } + assertFailsWith { + arr[Int.MAX_VALUE] = 1U + } + assertFailsWith { + arr[Int.MIN_VALUE] = 1U + } +} + +@Test fun shortArrayGet() { + val arr = ShortArray(10) { 0 } + assertEquals(0, arr[0]) + assertEquals(0, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun shortArraySet() { + val arr = ShortArray(10) { 0 } + arr[0] = 1 + arr[9] = 1 + assertFailsWith { + arr[10] = 1 + } + assertFailsWith { + arr[-1] = 1 + } + assertFailsWith { + arr[Int.MAX_VALUE] = 1 + } + assertFailsWith { + arr[Int.MIN_VALUE] = 1 + } +} + +@Test fun uShortArrayGet() { + val arr = UShortArray(10) { 0U } + assertEquals(0U, arr[0]) + assertEquals(0U, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun uShortArraySet() { + val arr = UShortArray(10) { 0U } + arr[0] = 1U + arr[9] = 1U + assertFailsWith { + arr[10] = 1U + } + assertFailsWith { + arr[-1] = 1U + } + assertFailsWith { + arr[Int.MAX_VALUE] = 1U + } + assertFailsWith { + arr[Int.MIN_VALUE] = 1U + } +} + +@Test fun intArrayGet() { + val arr = IntArray(10) { 0 } + assertEquals(0, arr[0]) + assertEquals(0, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun intArraySet() { + val arr = IntArray(10) { 0 } + arr[0] = 1 + arr[9] = 1 + assertFailsWith { + arr[10] = 1 + } + assertFailsWith { + arr[-1] = 1 + } + assertFailsWith { + arr[Int.MAX_VALUE] = 1 + } + assertFailsWith { + arr[Int.MIN_VALUE] = 1 + } +} + +@Test fun uIntArrayGet() { + val arr = UIntArray(10) { 0U } + assertEquals(0U, arr[0]) + assertEquals(0U, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun uIntArraySet() { + val arr = UIntArray(10) { 0U } + arr[0] = 1U + arr[9] = 1U + assertFailsWith { + arr[10] = 1U + } + assertFailsWith { + arr[-1] = 1U + } + assertFailsWith { + arr[Int.MAX_VALUE] = 1U + } + assertFailsWith { + arr[Int.MIN_VALUE] = 1U + } +} + +@Test fun longArrayGet() { + val arr = LongArray(10) { 0 } + assertEquals(0, arr[0]) + assertEquals(0, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun longArraySet() { + val arr = LongArray(10) { 0 } + arr[0] = 1 + arr[9] = 1 + assertFailsWith { + arr[10] = 1 + } + assertFailsWith { + arr[-1] = 1 + } + assertFailsWith { + arr[Int.MAX_VALUE] = 1 + } + assertFailsWith { + arr[Int.MIN_VALUE] = 1 + } +} + +@Test fun uLongArrayGet() { + val arr = ULongArray(10) { 0U } + assertEquals(0U, arr[0]) + assertEquals(0U, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun uLongArraySet() { + val arr = ULongArray(10) { 0U } + arr[0] = 1U + arr[9] = 1U + assertFailsWith { + arr[10] = 1U + } + assertFailsWith { + arr[-1] = 1U + } + assertFailsWith { + arr[Int.MAX_VALUE] = 1U + } + assertFailsWith { + arr[Int.MIN_VALUE] = 1U + } +} + +@Test fun floatArrayGet() { + val arr = FloatArray(10) { 0.0f } + assertEquals(0.0f, arr[0]) + assertEquals(0.0f, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun floatArraySet() { + val arr = FloatArray(10) { 0.0f } + arr[0] = 1.0f + arr[9] = 1.0f + assertFailsWith { + arr[10] = 1.0f + } + assertFailsWith { + arr[-1] = 1.0f + } + assertFailsWith { + arr[Int.MAX_VALUE] = 1.0f + } + assertFailsWith { + arr[Int.MIN_VALUE] = 1.0f + } +} + +@Test fun doubleArrayGet() { + val arr = DoubleArray(10) { 0.0 } + assertEquals(0.0, arr[0]) + assertEquals(0.0, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun doubleArraySet() { + val arr = DoubleArray(10) { 0.0 } + arr[0] = 1.0 + arr[9] = 1.0 + assertFailsWith { + arr[10] = 1.0 + } + assertFailsWith { + arr[-1] = 1.0 + } + assertFailsWith { + arr[Int.MAX_VALUE] = 1.0 + } + assertFailsWith { + arr[Int.MIN_VALUE] = 1.0 + } +} + +@Test fun booleanArrayGet() { + val arr = BooleanArray(10) { false } + assertEquals(false, arr[0]) + assertEquals(false, arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun booleanArraySet() { + val arr = BooleanArray(10) { false } + arr[0] = true + arr[9] = true + assertFailsWith { + arr[10] = true + } + assertFailsWith { + arr[-1] = true + } + assertFailsWith { + arr[Int.MAX_VALUE] = true + } + assertFailsWith { + arr[Int.MIN_VALUE] = true + } +} + +@Test fun charArrayGet() { + val arr = CharArray(10) { '0' } + assertEquals('0', arr[0]) + assertEquals('0', arr[9]) + assertFailsWith { + arr[10] + } + assertFailsWith { + arr[-1] + } + assertFailsWith { + arr[Int.MAX_VALUE] + } + assertFailsWith { + arr[Int.MIN_VALUE] + } +} + +@Test fun charArraySet() { + val arr = CharArray(10) { '0' } + arr[0] = '1' + arr[9] = '1' + assertFailsWith { + arr[10] = '1' + } + assertFailsWith { + arr[-1] = '1' + } + assertFailsWith { + arr[Int.MAX_VALUE] = '1' + } + assertFailsWith { + arr[Int.MIN_VALUE] = '1' + } +} + +@Test fun byteArrayGetUByte() { + val arr = ByteArray(10) { 0 } + assertEquals(0U, arr.getUByteAt(0)) + assertEquals(0U, arr.getUByteAt(9)) + assertFailsWith { + arr.getUByteAt(10) + } + assertFailsWith { + arr.getUByteAt(-1) + } + assertFailsWith { + arr.getUByteAt(Int.MAX_VALUE) + } + assertFailsWith { + arr.getUByteAt(Int.MIN_VALUE) + } +} + +@Test fun byteArraySetUByte() { + val arr = ByteArray(10) { 0 } + arr.setUByteAt(0, 1U) + arr.setUByteAt(9, 1U) + assertFailsWith { + arr.setUByteAt(10, 1U) + } + assertFailsWith { + arr.setUByteAt(-1, 1U) + } + assertFailsWith { + arr.setUByteAt(Int.MAX_VALUE, 1U) + } + assertFailsWith { + arr.setUByteAt(Int.MIN_VALUE, 1U) + } +} + +@Test fun byteArrayGetChar() { + val arr = ByteArray(10) { 0 } + assertEquals(0.toChar(), arr.getCharAt(0)) + assertEquals(0.toChar(), arr.getCharAt(8)) + assertFailsWith { + arr.getCharAt(9) + } + assertFailsWith { + arr.getCharAt(10) + } + assertFailsWith { + arr.getCharAt(-1) + } + assertFailsWith { + arr.getCharAt(Int.MAX_VALUE) + } + assertFailsWith { + arr.getCharAt(Int.MIN_VALUE) + } +} + +@Test fun byteArraySetChar() { + val arr = ByteArray(10) { 0 } + arr.setCharAt(0, '1') + arr.setCharAt(8, '1') + assertFailsWith { + arr.setCharAt(9, '1') + } + assertFailsWith { + arr.setCharAt(10, '1') + } + assertFailsWith { + arr.setCharAt(-1, '1') + } + assertFailsWith { + arr.setCharAt(Int.MAX_VALUE, '1') + } + assertFailsWith { + arr.setCharAt(Int.MIN_VALUE, '1') + } +} + +@Test fun byteArrayGetShort() { + val arr = ByteArray(10) { 0 } + assertEquals(0, arr.getShortAt(0)) + assertEquals(0, arr.getShortAt(8)) + assertFailsWith { + arr.getShortAt(9) + } + assertFailsWith { + arr.getShortAt(10) + } + assertFailsWith { + arr.getShortAt(-1) + } + assertFailsWith { + arr.getShortAt(Int.MAX_VALUE) + } + assertFailsWith { + arr.getShortAt(Int.MIN_VALUE) + } +} + +@Test fun byteArraySetShort() { + val arr = ByteArray(10) { 0 } + arr.setShortAt(0, 0) + arr.setShortAt(8, 0) + assertFailsWith { + arr.setShortAt(9, 1) + } + assertFailsWith { + arr.setShortAt(10, 1) + } + assertFailsWith { + arr.setShortAt(-1, 1) + } + assertFailsWith { + arr.setShortAt(Int.MAX_VALUE, 1) + } + assertFailsWith { + arr.setShortAt(Int.MIN_VALUE, 1) + } +} + +@Test fun byteArrayGetUShort() { + val arr = ByteArray(10) { 0 } + assertEquals(0U, arr.getUShortAt(0)) + assertEquals(0U, arr.getUShortAt(8)) + assertFailsWith { + arr.getUShortAt(9) + } + assertFailsWith { + arr.getUShortAt(10) + } + assertFailsWith { + arr.getUShortAt(-1) + } + assertFailsWith { + arr.getUShortAt(Int.MAX_VALUE) + } + assertFailsWith { + arr.getUShortAt(Int.MIN_VALUE) + } +} + +@Test fun byteArraySetUShort() { + val arr = ByteArray(10) { 0 } + arr.setUShortAt(0, 0U) + arr.setUShortAt(8, 0U) + assertFailsWith { + arr.setUShortAt(9, 1U) + } + assertFailsWith { + arr.setUShortAt(10, 1U) + } + assertFailsWith { + arr.setUShortAt(-1, 1U) + } + assertFailsWith { + arr.setUShortAt(Int.MAX_VALUE, 1U) + } + assertFailsWith { + arr.setUShortAt(Int.MIN_VALUE, 1U) + } +} + +@Test fun byteArrayGetInt() { + val arr = ByteArray(10) { 0 } + assertEquals(0, arr.getIntAt(0)) + assertEquals(0, arr.getIntAt(6)) + assertFailsWith { + arr.getIntAt(7) + } + assertFailsWith { + arr.getIntAt(10) + } + assertFailsWith { + arr.getIntAt(-1) + } + assertFailsWith { + arr.getIntAt(Int.MAX_VALUE) + } + assertFailsWith { + arr.getIntAt(Int.MIN_VALUE) + } +} + +@Test fun byteArraySetInt() { + val arr = ByteArray(10) { 0 } + arr.setIntAt(0, 1) + arr.setIntAt(6, 1) + assertFailsWith { + arr.setIntAt(7, 1) + } + assertFailsWith { + arr.setIntAt(10, 1) + } + assertFailsWith { + arr.setIntAt(-1, 1) + } + assertFailsWith { + arr.setIntAt(Int.MAX_VALUE, 1) + } + assertFailsWith { + arr.setIntAt(Int.MIN_VALUE, 1) + } +} + +@Test fun byteArrayGetUInt() { + val arr = ByteArray(10) { 0 } + assertEquals(0U, arr.getUIntAt(0)) + assertEquals(0U, arr.getUIntAt(6)) + assertFailsWith { + arr.getUIntAt(7) + } + assertFailsWith { + arr.getUIntAt(10) + } + assertFailsWith { + arr.getUIntAt(-1) + } + assertFailsWith { + arr.getUIntAt(Int.MAX_VALUE) + } + assertFailsWith { + arr.getUIntAt(Int.MIN_VALUE) + } +} + +@Test fun byteArraySetUInt() { + val arr = ByteArray(10) { 0 } + arr.setUIntAt(0, 1U) + arr.setUIntAt(6, 1U) + assertFailsWith { + arr.setUIntAt(7, 1U) + } + assertFailsWith { + arr.setUIntAt(10, 1U) + } + assertFailsWith { + arr.setUIntAt(-1, 1U) + } + assertFailsWith { + arr.setUIntAt(Int.MAX_VALUE, 1U) + } + assertFailsWith { + arr.setUIntAt(Int.MIN_VALUE, 1U) + } +} + +@Test fun byteArrayGetLong() { + val arr = ByteArray(10) { 0 } + assertEquals(0, arr.getLongAt(0)) + assertEquals(0, arr.getLongAt(2)) + assertFailsWith { + arr.getLongAt(3) + } + assertFailsWith { + arr.getLongAt(10) + } + assertFailsWith { + arr.getLongAt(-1) + } + assertFailsWith { + arr.getLongAt(Int.MAX_VALUE) + } + assertFailsWith { + arr.getLongAt(Int.MIN_VALUE) + } +} + +@Test fun byteArraySetLong() { + val arr = ByteArray(10) { 0 } + arr.setLongAt(0, 1) + arr.setLongAt(2, 1) + assertFailsWith { + arr.setLongAt(3, 1) + } + assertFailsWith { + arr.setLongAt(10, 1) + } + assertFailsWith { + arr.setLongAt(-1, 1) + } + assertFailsWith { + arr.setLongAt(Int.MAX_VALUE, 1) + } + assertFailsWith { + arr.setLongAt(Int.MIN_VALUE, 1) + } +} + +@Test fun byteArrayGetULong() { + val arr = ByteArray(10) { 0 } + assertEquals(0U, arr.getULongAt(0)) + assertEquals(0U, arr.getULongAt(2)) + assertFailsWith { + arr.getULongAt(3) + } + assertFailsWith { + arr.getULongAt(10) + } + assertFailsWith { + arr.getULongAt(-1) + } + assertFailsWith { + arr.getULongAt(Int.MAX_VALUE) + } + assertFailsWith { + arr.getULongAt(Int.MIN_VALUE) + } +} + +@Test fun byteArraySetULong() { + val arr = ByteArray(10) { 0 } + arr.setULongAt(0, 1U) + arr.setULongAt(2, 1U) + assertFailsWith { + arr.setULongAt(3, 1U) + } + assertFailsWith { + arr.setULongAt(10, 1U) + } + assertFailsWith { + arr.setULongAt(-1, 1U) + } + assertFailsWith { + arr.setULongAt(Int.MAX_VALUE, 1U) + } + assertFailsWith { + arr.setULongAt(Int.MIN_VALUE, 1U) + } +} + +@Test fun byteArrayGetFloat() { + val arr = ByteArray(10) { 0 } + assertEquals(0.0f, arr.getFloatAt(0)) + assertEquals(0.0f, arr.getFloatAt(6)) + assertFailsWith { + arr.getFloatAt(7) + } + assertFailsWith { + arr.getFloatAt(10) + } + assertFailsWith { + arr.getFloatAt(-1) + } + assertFailsWith { + arr.getFloatAt(Int.MAX_VALUE) + } + assertFailsWith { + arr.getFloatAt(Int.MIN_VALUE) + } +} + +@Test fun byteArraySetFloat() { + val arr = ByteArray(10) { 0 } + arr.setFloatAt(0, 1.0f) + arr.setFloatAt(6, 1.0f) + assertFailsWith { + arr.setFloatAt(7, 1.0f) + } + assertFailsWith { + arr.setFloatAt(10, 1.0f) + } + assertFailsWith { + arr.setFloatAt(-1, 1.0f) + } + assertFailsWith { + arr.setFloatAt(Int.MAX_VALUE, 1.0f) + } + assertFailsWith { + arr.setFloatAt(Int.MIN_VALUE, 1.0f) + } +} + +@Test fun byteArrayGetDouble() { + val arr = ByteArray(10) { 0 } + assertEquals(0.0, arr.getDoubleAt(0)) + assertEquals(0.0, arr.getDoubleAt(2)) + assertFailsWith { + arr.getDoubleAt(3) + } + assertFailsWith { + arr.getDoubleAt(10) + } + assertFailsWith { + arr.getDoubleAt(-1) + } + assertFailsWith { + arr.getDoubleAt(Int.MAX_VALUE) + } + assertFailsWith { + arr.getDoubleAt(Int.MIN_VALUE) + } +} + +@Test fun byteArraySetDouble() { + val arr = ByteArray(10) { 0 } + arr.setDoubleAt(0, 1.0) + arr.setDoubleAt(2, 1.0) + assertFailsWith { + arr.setDoubleAt(3, 1.0) + } + assertFailsWith { + arr.setDoubleAt(10, 1.0) + } + assertFailsWith { + arr.setDoubleAt(-1, 1.0) + } + assertFailsWith { + arr.setDoubleAt(Int.MAX_VALUE, 1.0) + } + assertFailsWith { + arr.setDoubleAt(Int.MIN_VALUE, 1.0) + } +} + +@Test fun immutableBlobToByteArray() { + val blob = immutableBlobOf(0, 0) + val arr = blob.toByteArray(0, 1) + assertEquals(1, arr.size) + assertEquals(0, arr[0]) + assertFailsWith { + blob.toByteArray(-1, 1) + } + assertFailsWith { + blob.toByteArray(0, -1) + } + assertFailsWith { + blob.toByteArray(0, 10) + } + assertFailsWith { + blob.toByteArray(10, 11) + } + assertFailsWith { + blob.toByteArray(10, 1) + } +} + +@Test fun immutableBlobToUByteArray() { + val blob = immutableBlobOf(0, 0) + val arr = blob.toUByteArray(0, 1) + assertEquals(1, arr.size) + assertEquals(0U, arr[0]) + assertFailsWith { + blob.toUByteArray(-1, 1) + } + assertFailsWith { + blob.toUByteArray(0, -1) + } + assertFailsWith { + blob.toUByteArray(0, 10) + } + assertFailsWith { + blob.toUByteArray(10, 11) + } + assertFailsWith { + blob.toUByteArray(10, 1) + } +} + +@Test fun immutableBlobAsCPointer() { + val blob = immutableBlobOf(0, 0) + assertEquals(0, blob.asCPointer(0).pointed.value) + assertFailsWith { + blob.asCPointer(10) + } + assertFailsWith { + blob.asCPointer(-1) + } + assertFailsWith { + blob.asCPointer(Int.MAX_VALUE) + } + assertFailsWith { + blob.asCPointer(Int.MIN_VALUE) + } +} + +@Test fun immutableBlobAsUCPointer() { + val blob = immutableBlobOf(0, 0) + assertEquals(0U, blob.asUCPointer(0).pointed.value) + assertFailsWith { + blob.asUCPointer(10) + } + assertFailsWith { + blob.asUCPointer(-1) + } + assertFailsWith { + blob.asUCPointer(Int.MAX_VALUE) + } + assertFailsWith { + blob.asUCPointer(Int.MIN_VALUE) + } +} diff --git a/build-tools/src/main/kotlin/org/jetbrains/kotlin/CompileToBitcode.kt b/build-tools/src/main/kotlin/org/jetbrains/kotlin/CompileToBitcode.kt index 5b21e2d5a7a..237deaaad7d 100644 --- a/build-tools/src/main/kotlin/org/jetbrains/kotlin/CompileToBitcode.kt +++ b/build-tools/src/main/kotlin/org/jetbrains/kotlin/CompileToBitcode.kt @@ -67,7 +67,8 @@ open class CompileToBitcode @Inject constructor(@InputDirectory val srcRoot: Fil "-Werror", "-ftls-model=initial-exec", "-Wno-unused-function") Language.CPP -> listOfNotNull("-std=c++14", "-Werror", "-O2", - "-Wall", + "-Wall", "-Wextra", + "-Wno-unused-parameter", // False positives with polymorphic functions. "-Wno-unused-function", // TODO: Enable this warning when we have C++ runtime tests. "-fPIC".takeIf { !HostManager().targetByName(target).isMINGW }) } diff --git a/common/src/hash/cpp/Names.cpp b/common/src/hash/cpp/Names.cpp index 0016f40db82..182eeef3cc7 100644 --- a/common/src/hash/cpp/Names.cpp +++ b/common/src/hash/cpp/Names.cpp @@ -29,7 +29,7 @@ constexpr uint32_t PrintableHexSize(uint32_t input_length) { void PrintableHex(const uint8_t* data, uint32_t data_length, char* hex) { static const char* hex_digits = "0123456789ABCDEF"; - for(int i = 0; i < data_length; ++i) { + for (uint32_t i = 0; i < data_length; ++i) { *hex++ = hex_digits[(*data >> 4) & 0xf]; *hex++ = hex_digits[(*data++) & 0xf]; } diff --git a/runtime/src/debug/cpp/KDebug.cpp b/runtime/src/debug/cpp/KDebug.cpp index e990374da5a..a535034522b 100644 --- a/runtime/src/debug/cpp/KDebug.cpp +++ b/runtime/src/debug/cpp/KDebug.cpp @@ -113,7 +113,8 @@ int32_t Konan_DebugObjectToUtf8ArrayImpl(KRef obj, char* buffer, int32_t bufferS ObjHolder stringHolder; auto data = KonanObjectToUtf8Array(obj, stringHolder.slot())->array(); if (data == nullptr) return 0; - KInt toCopy = data->count_ > bufferSize - 1 ? bufferSize - 1 : data->count_; + if (bufferSize < 1) return 0; + KInt toCopy = data->count_ > static_cast(bufferSize - 1) ? bufferSize - 1 : data->count_; ::memcpy(buffer, ByteArrayAddressOfElementAt(data, 0), toCopy); buffer[toCopy] = '\0'; return toCopy + 1; @@ -176,7 +177,7 @@ void* Konan_DebugGetFieldAddressImpl(KRef obj, int32_t index) { return nullptr; if (extendedTypeInfo->fieldsCount_ < 0) { - if (index > obj->array()->count_) + if (static_cast(index) > obj->array()->count_) return nullptr; int32_t typeIndex = -extendedTypeInfo->fieldsCount_; diff --git a/runtime/src/debug/cpp/SourceInfo.cpp b/runtime/src/debug/cpp/SourceInfo.cpp index 4e7f2fb727f..e036ef8ec66 100644 --- a/runtime/src/debug/cpp/SourceInfo.cpp +++ b/runtime/src/debug/cpp/SourceInfo.cpp @@ -18,11 +18,11 @@ #ifdef KONAN_CORE_SYMBOLICATION #include +#include #include -#include -#include -#include +#include #include +#include #define TRACE_SYMBOLICATION 0 #if TRACE_SYMBOLICATION @@ -51,7 +51,7 @@ typedef struct _CSRange { typedef unsigned long long CSArchitecture; -#define kCSNow LLONG_MAX +constexpr auto kCSNow = std::numeric_limits::max(); namespace { @@ -153,7 +153,8 @@ extern "C" struct SourceInfo Kotlin_getSourceInfo(void* addr) { */ CSSymbolForeachSourceInfo(symbol, ^(CSSourceInfoRef ref) { - uint32_t lineNumber = CSSourceInfoGetLineNumber(ref); + // Expecting CSSourceInfoGetLineNumber not to overflow int32_t max value. + int32_t lineNumber = CSSourceInfoGetLineNumber(ref); if (lineNumber == 0) return 0; if (limits.start == -1) { @@ -170,7 +171,8 @@ extern "C" struct SourceInfo Kotlin_getSourceInfo(void* addr) { CSSymbolForeachSourceInfo(symbol, ^(CSSourceInfoRef ref) { - uint32_t lineNumber = CSSourceInfoGetLineNumber(ref); + // Expecting CSSourceInfoGetLineNumber not to overflow int32_t max value. + int32_t lineNumber = CSSourceInfoGetLineNumber(ref); if (lineNumber == 0) return 0; SYM_DUMP(ref); diff --git a/runtime/src/launcher/cpp/androidLauncher.cpp b/runtime/src/launcher/cpp/androidLauncher.cpp index 16348390a80..ebbd8a4d636 100644 --- a/runtime/src/launcher/cpp/androidLauncher.cpp +++ b/runtime/src/launcher/cpp/androidLauncher.cpp @@ -143,13 +143,13 @@ void onStart(ANativeActivity* activity) { void onResume(ANativeActivity* activity) { LOGV("onResume called"); - NativeActivitySaveStateEvent event = { RESUME }; + NativeActivitySaveStateEvent event = { RESUME, nullptr, 0 }; putEventSynchronously(&event); } void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { LOGV("onSaveInstanceState called"); - NativeActivitySaveStateEvent event = { SAVE_INSTANCE_STATE }; + NativeActivitySaveStateEvent event = { SAVE_INSTANCE_STATE, nullptr, 0 }; putEventSynchronously(&event); *outLen = event.savedStateSize; return event.savedState; diff --git a/runtime/src/main/cpp/Arrays.cpp b/runtime/src/main/cpp/Arrays.cpp index 7d0e622d62a..a8d7b3c0659 100644 --- a/runtime/src/main/cpp/Arrays.cpp +++ b/runtime/src/main/cpp/Arrays.cpp @@ -34,6 +34,15 @@ ALWAYS_INLINE inline void mutabilityCheck(KConstRef thiz) { } } +ALWAYS_INLINE inline void boundsCheck(const ArrayHeader* array, KInt index) { + // We couldn't have created an array bigger than max KInt value. + // So if index is < 0, conversion to an unsigned value would make it bigger + // than the array size. + if (static_cast(index) >= array->count_) { + ThrowArrayIndexOutOfBoundsException(); + } +} + template inline void fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, T value) { ArrayHeader* array = thiz->array(); @@ -65,9 +74,7 @@ inline void copyImpl(KConstRef thiz, KInt fromIndex, template inline void PrimitiveArraySet(KRef thiz, KInt index, T value) { ArrayHeader* array = thiz->array(); - if (static_cast(index) >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); mutabilityCheck(thiz); *PrimitiveArrayAddressOfElementAt(array, index) = value; } @@ -75,9 +82,7 @@ inline void PrimitiveArraySet(KRef thiz, KInt index, T value) { template inline T PrimitiveArrayGet(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); - if (static_cast(index) >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); return *PrimitiveArrayAddressOfElementAt(array, index); } @@ -93,17 +98,13 @@ extern const ObjHeader theEmptyArray; // Array.kt OBJ_GETTER(Kotlin_Array_get, KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); - if (static_cast(index) >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); RETURN_OBJ(*ArrayAddressOfElementAt(array, index)); } void Kotlin_Array_set(KRef thiz, KInt index, KConstRef value) { ArrayHeader* array = thiz->array(); - if (static_cast(index) >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); mutabilityCheck(thiz); UpdateHeapRef(ArrayAddressOfElementAt(array, index), value); } @@ -128,7 +129,7 @@ void Kotlin_Array_copyImpl(KConstRef thiz, KInt fromIndex, ArrayHeader* destinationArray = destination->array(); if (count < 0 || fromIndex < 0 || static_cast(count) + fromIndex > array->count_ || - toIndex < 0 || static_cast(count)+ toIndex > destinationArray->count_) { + toIndex < 0 || static_cast(count) + toIndex > destinationArray->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(destination); @@ -152,17 +153,13 @@ OBJ_GETTER0(Kotlin_emptyArray) { KByte Kotlin_ByteArray_get(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); - if (static_cast(index) >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); return *ByteArrayAddressOfElementAt(array, index); } void Kotlin_ByteArray_set(KRef thiz, KInt index, KByte value) { ArrayHeader* array = thiz->array(); - if (static_cast(index) >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); mutabilityCheck(thiz); *ByteArrayAddressOfElementAt(array, index) = value; } @@ -174,7 +171,7 @@ KInt Kotlin_ByteArray_getArrayLength(KConstRef thiz) { KChar Kotlin_ByteArray_getCharAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); - if (static_cast(index + 1) >= array->count_) { + if (index < 0 || static_cast(index) + 1 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS @@ -192,7 +189,7 @@ KChar Kotlin_ByteArray_getCharAt(KConstRef thiz, KInt index) { KShort Kotlin_ByteArray_getShortAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); - if (static_cast(index + 1) >= array->count_) { + if (index < 0 || static_cast(index) + 1 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS @@ -210,7 +207,7 @@ KShort Kotlin_ByteArray_getShortAt(KConstRef thiz, KInt index) { KInt Kotlin_ByteArray_getIntAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); - if (static_cast(index + 3) >= array->count_) { + if (index < 0 || static_cast(index) + 3 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS @@ -229,7 +226,7 @@ KInt Kotlin_ByteArray_getIntAt(KConstRef thiz, KInt index) { KLong Kotlin_ByteArray_getLongAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); - if (static_cast(index + 7) >= array->count_) { + if (index < 0 || static_cast(index) + 7 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS @@ -250,7 +247,7 @@ KLong Kotlin_ByteArray_getLongAt(KConstRef thiz, KInt index) { KFloat Kotlin_ByteArray_getFloatAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); - if (static_cast(index + 3) >= array->count_) { + if (index < 0 || static_cast(index) + 3 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS @@ -279,7 +276,7 @@ KFloat Kotlin_ByteArray_getFloatAt(KConstRef thiz, KInt index) { KDouble Kotlin_ByteArray_getDoubleAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); - if (static_cast(index + 7) >= array->count_) { + if (index < 0 || static_cast(index) + 7 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS @@ -315,7 +312,7 @@ KDouble Kotlin_ByteArray_getDoubleAt(KConstRef thiz, KInt index) { void Kotlin_ByteArray_setCharAt(KRef thiz, KInt index, KChar value) { ArrayHeader* array = thiz->array(); - if (static_cast(index + 1) >= array->count_) { + if (index < 0 || static_cast(index) + 1 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); @@ -333,7 +330,7 @@ void Kotlin_ByteArray_setCharAt(KRef thiz, KInt index, KChar value) { void Kotlin_ByteArray_setShortAt(KRef thiz, KInt index, KShort value) { ArrayHeader* array = thiz->array(); - if (static_cast(index + 1) >= array->count_) { + if (index < 0 || static_cast(index) + 1 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); @@ -351,7 +348,7 @@ void Kotlin_ByteArray_setShortAt(KRef thiz, KInt index, KShort value) { void Kotlin_ByteArray_setIntAt(KRef thiz, KInt index, KInt value) { ArrayHeader* array = thiz->array(); - if (static_cast(index + 3) >= array->count_) { + if (index < 0 || static_cast(index) + 3 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); @@ -371,7 +368,7 @@ void Kotlin_ByteArray_setIntAt(KRef thiz, KInt index, KInt value) { void Kotlin_ByteArray_setLongAt(KRef thiz, KInt index, KLong value) { ArrayHeader* array = thiz->array(); - if (static_cast(index + 7) >= array->count_) { + if (index < 0 || static_cast(index) + 7 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); @@ -395,7 +392,7 @@ void Kotlin_ByteArray_setLongAt(KRef thiz, KInt index, KLong value) { void Kotlin_ByteArray_setFloatAt(KRef thiz, KInt index, KFloat value) { ArrayHeader* array = thiz->array(); - if (static_cast(index + 3) >= array->count_) { + if (index < 0 || static_cast(index) + 3 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); @@ -417,7 +414,7 @@ void Kotlin_ByteArray_setFloatAt(KRef thiz, KInt index, KFloat value) { void Kotlin_ByteArray_setDoubleAt(KRef thiz, KInt index, KDouble value) { ArrayHeader* array = thiz->array(); - if (static_cast(index + 7) >= array->count_) { + if (index < 0 || static_cast(index) + 7 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); @@ -455,7 +452,7 @@ OBJ_GETTER(Kotlin_CharArray_copyOf, KConstRef thiz, KInt newSize) { ThrowIllegalArgumentException(); } ArrayHeader* result = AllocArrayInstance(array->type_info(), newSize, OBJ_RESULT)->array(); - KInt toCopy = array->count_ < newSize ? array->count_ : newSize; + KInt toCopy = array->count_ < static_cast(newSize) ? array->count_ : newSize; memcpy( PrimitiveArrayAddressOfElementAt(result, 0), PrimitiveArrayAddressOfElementAt(array, 0), @@ -633,8 +630,8 @@ KInt Kotlin_NativePtrArray_getArrayLength(KConstRef thiz) { OBJ_GETTER(Kotlin_ImmutableBlob_toByteArray, KConstRef thiz, KInt startIndex, KInt endIndex) { const ArrayHeader* array = thiz->array(); - if (startIndex < 0 || endIndex > array->count_ || startIndex > endIndex) { - ThrowArrayIndexOutOfBoundsException(); + if (startIndex < 0 || static_cast(endIndex) > array->count_ || startIndex > endIndex) { + ThrowArrayIndexOutOfBoundsException(); } KInt count = endIndex - startIndex; ArrayHeader* result = AllocArrayInstance(theByteArrayTypeInfo, count, OBJ_RESULT)->array(); @@ -646,23 +643,26 @@ OBJ_GETTER(Kotlin_ImmutableBlob_toByteArray, KConstRef thiz, KInt startIndex, KI KNativePtr Kotlin_ImmutableBlob_asCPointerImpl(KRef thiz, KInt offset) { ArrayHeader* array = thiz->array(); - if (offset < 0 || offset > array->count_) { - ThrowArrayIndexOutOfBoundsException(); + // We couldn't have created an array bigger than max KInt value. + // So if index is < 0, conversion to an unsigned value would make it bigger + // than the array size. + if (static_cast(offset) > array->count_) { + ThrowArrayIndexOutOfBoundsException(); } return PrimitiveArrayAddressOfElementAt(array, offset); } KNativePtr Kotlin_Arrays_getByteArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); - if (index < 0 || index >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); return AddressOfElementAt(array, index); } KNativePtr Kotlin_Arrays_getCharArrayAddressOfElement (KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); + boundsCheck(array, index); + return CharArrayAddressOfElementAt(array, index); } @@ -672,45 +672,35 @@ KNativePtr Kotlin_Arrays_getStringAddressOfElement (KRef thiz, KInt index) { KNativePtr Kotlin_Arrays_getShortArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); - if (index < 0 || index >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); return AddressOfElementAt(array, index); } KNativePtr Kotlin_Arrays_getIntArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); - if (index < 0 || index >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); return AddressOfElementAt(array, index); } KNativePtr Kotlin_Arrays_getLongArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); - if (index < 0 || index >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); return AddressOfElementAt(array, index); } KNativePtr Kotlin_Arrays_getFloatArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); - if (index < 0 || index >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); return AddressOfElementAt(array, index); } KNativePtr Kotlin_Arrays_getDoubleArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); - if (index < 0 || index >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + boundsCheck(array, index); return AddressOfElementAt(array, index); } diff --git a/runtime/src/main/cpp/CyclicCollector.cpp b/runtime/src/main/cpp/CyclicCollector.cpp index 08f7660d723..800ba285e64 100644 --- a/runtime/src/main/cpp/CyclicCollector.cpp +++ b/runtime/src/main/cpp/CyclicCollector.cpp @@ -96,7 +96,7 @@ inline void traverseObjectFields(ObjHeader* obj, func process) { } } else { ArrayHeader* array = obj->array(); - for (int index = 0; index < array->count_; index++) { + for (uint32_t index = 0; index < array->count_; index++) { process(ArrayAddressOfElementAt(array, index)); } } @@ -242,7 +242,7 @@ class CyclicCollector { RuntimeAssert(objContainer->frozen(), "Must be frozen aggregate"); ContainerHeader** subContainer = reinterpret_cast(objContainer + 1); refCount = 0; - for (int i = 0; i < objContainer->objectCount(); ++i) { + for (uint32_t i = 0; i < objContainer->objectCount(); ++i) { auto* componentObj = reinterpret_cast((*subContainer) + 1); refCount += sideRefCounts[componentObj]; subContainer++; diff --git a/runtime/src/main/cpp/Exceptions.cpp b/runtime/src/main/cpp/Exceptions.cpp index 6ae34e90756..88e282d6140 100644 --- a/runtime/src/main/cpp/Exceptions.cpp +++ b/runtime/src/main/cpp/Exceptions.cpp @@ -161,7 +161,7 @@ OBJ_GETTER(GetStackTraceStrings, KConstRef stackTrace) { ObjHolder resultHolder; ObjHeader* strings = AllocArrayInstance(theArrayTypeInfo, size, resultHolder.slot()); #if USE_GCC_UNWIND - for (int index = 0; index < size; ++index) { + for (uint32_t index = 0; index < size; ++index) { KNativePtr address = Kotlin_NativePtrArray_get(stackTrace, index); char symbol[512]; if (!AddressToSymbol((const void*) address, symbol, sizeof(symbol))) { @@ -179,7 +179,7 @@ OBJ_GETTER(GetStackTraceStrings, KConstRef stackTrace) { char **symbols = backtrace_symbols(PrimitiveArrayAddressOfElementAt(stackTrace->array(), 0), size); RuntimeCheck(symbols != nullptr, "Not enough memory to retrieve the stacktrace"); - for (int index = 0; index < size; ++index) { + for (uint32_t index = 0; index < size; ++index) { auto sourceInfo = getSourceInfo(stackTrace, index); const char* symbol = symbols[index]; const char* result; diff --git a/runtime/src/main/cpp/ExecFormat.cpp b/runtime/src/main/cpp/ExecFormat.cpp index f5bd74669dd..d9f71f54417 100644 --- a/runtime/src/main/cpp/ExecFormat.cpp +++ b/runtime/src/main/cpp/ExecFormat.cpp @@ -153,7 +153,7 @@ extern "C" bool AddressToSymbol(const void* address, char* resultBuffer, size_t namespace { static void* mapModuleFile(HMODULE hModule) { - int bufferLength = 64; + DWORD bufferLength = 64; wchar_t* buffer = nullptr; for (;;) { auto newBuffer = (wchar_t*)konanAllocMemory(sizeof(wchar_t) * bufferLength); diff --git a/runtime/src/main/cpp/KString.cpp b/runtime/src/main/cpp/KString.cpp index a0658880b9f..bcfcedd7628 100644 --- a/runtime/src/main/cpp/KString.cpp +++ b/runtime/src/main/cpp/KString.cpp @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include #include #include "KAssert.h" @@ -734,12 +736,12 @@ OBJ_GETTER(Kotlin_String_replace, KString thiz, KChar oldChar, KChar newChar, KB KChar* resultRaw = CharArrayAddressOfElementAt(result, 0); if (ignoreCase) { KChar oldCharLower = towlower_Konan(oldChar); - for (KInt index = 0; index < count; ++index) { + for (uint32_t index = 0; index < count; ++index) { KChar thizChar = *thizRaw++; *resultRaw++ = towlower_Konan(thizChar) == oldCharLower ? newChar : thizChar; } } else { - for (KInt index = 0; index < count; ++index) { + for (uint32_t index = 0; index < count; ++index) { KChar thizChar = *thizRaw++; *resultRaw++ = thizChar == oldChar ? newChar : thizChar; } @@ -752,8 +754,11 @@ OBJ_GETTER(Kotlin_String_plusImpl, KString thiz, KString other) { RuntimeAssert(other != nullptr, "other cannot be null"); RuntimeAssert(thiz->type_info() == theStringTypeInfo, "Must be a string"); RuntimeAssert(other->type_info() == theStringTypeInfo, "Must be a string"); - KInt result_length = thiz->count_ + other->count_; - if (result_length < thiz->count_ || result_length < other->count_) { + RuntimeAssert(thiz->count_ <= static_cast(std::numeric_limits::max()), "this cannot be this large"); + RuntimeAssert(other->count_ <= static_cast(std::numeric_limits::max()), "other cannot be this large"); + // Since thiz and other sizes are bounded by int32_t max value, their sum cannot exceed uint32_t max value - 1. + uint32_t result_length = thiz->count_ + other->count_; + if (result_length > static_cast(std::numeric_limits::max())) { ThrowArrayIndexOutOfBoundsException(); } ArrayHeader* result = AllocArrayInstance(theStringTypeInfo, result_length, OBJ_RESULT)->array(); @@ -773,7 +778,7 @@ OBJ_GETTER(Kotlin_String_toUpperCase, KString thiz) { ArrayHeader* result = AllocArrayInstance(theStringTypeInfo, count, OBJ_RESULT)->array(); const KChar* thizRaw = CharArrayAddressOfElementAt(thiz, 0); KChar* resultRaw = CharArrayAddressOfElementAt(result, 0); - for (KInt index = 0; index < count; ++index) { + for (uint32_t index = 0; index < count; ++index) { *resultRaw++ = towupper_Konan(*thizRaw++); } RETURN_OBJ(result->obj()); @@ -784,7 +789,7 @@ OBJ_GETTER(Kotlin_String_toLowerCase, KString thiz) { ArrayHeader* result = AllocArrayInstance(theStringTypeInfo, count, OBJ_RESULT)->array(); const KChar* thizRaw = CharArrayAddressOfElementAt(thiz, 0); KChar* resultRaw = CharArrayAddressOfElementAt(result, 0); - for (KInt index = 0; index < count; ++index) { + for (uint32_t index = 0; index < count; ++index) { *resultRaw++ = towlower_Konan(*thizRaw++); } RETURN_OBJ(result->obj()); @@ -814,7 +819,7 @@ OBJ_GETTER(Kotlin_String_toCharArray, KString string, KInt start, KInt size) { } OBJ_GETTER(Kotlin_String_subSequence, KString thiz, KInt startIndex, KInt endIndex) { - if (startIndex < 0 || endIndex > thiz->count_ || startIndex > endIndex) { + if (startIndex < 0 || static_cast(endIndex) > thiz->count_ || startIndex > endIndex) { // TODO: is it correct exception? ThrowArrayIndexOutOfBoundsException(); } @@ -849,7 +854,7 @@ KInt Kotlin_String_compareToIgnoreCase(KString thiz, KConstRef other) { auto count = thiz->count_ < otherString->count_ ? thiz->count_ : otherString->count_; const KChar* thizRaw = CharArrayAddressOfElementAt(thiz, 0); const KChar* otherRaw = CharArrayAddressOfElementAt(otherString, 0); - for (KInt index = 0; index < count; ++index) { + for (uint32_t index = 0; index < count; ++index) { int diff = towlower_Konan(*thizRaw++) - towlower_Konan(*otherRaw++); if (diff != 0) return diff < 0 ? -1 : 1; @@ -864,6 +869,9 @@ KInt Kotlin_String_compareToIgnoreCase(KString thiz, KConstRef other) { KChar Kotlin_String_get(KString thiz, KInt index) { + // We couldn't have created a string bigger than max KInt value. + // So if index is < 0, conversion to an unsigned value would make it bigger + // than the array size. if (static_cast(index) >= thiz->count_) { ThrowArrayIndexOutOfBoundsException(); } @@ -906,8 +914,8 @@ OBJ_GETTER(Kotlin_String_unsafeStringToUtf8OrThrow, KString thiz, KInt start, KI KInt Kotlin_StringBuilder_insertString(KRef builder, KInt distIndex, KString fromString, KInt sourceIndex, KInt count) { auto toArray = builder->array(); - RuntimeAssert(sourceIndex >= 0 && sourceIndex + count <= fromString->count_, "must be true"); - RuntimeAssert(distIndex >= 0 && distIndex + count <= toArray->count_, "must be true"); + RuntimeAssert(sourceIndex >= 0 && static_cast(sourceIndex + count) <= fromString->count_, "must be true"); + RuntimeAssert(distIndex >= 0 && static_cast(distIndex + count) <= toArray->count_, "must be true"); memcpy(CharArrayAddressOfElementAt(toArray, distIndex), CharArrayAddressOfElementAt(fromString, sourceIndex), count * sizeof(KChar)); @@ -916,11 +924,11 @@ KInt Kotlin_StringBuilder_insertString(KRef builder, KInt distIndex, KString fro KInt Kotlin_StringBuilder_insertInt(KRef builder, KInt position, KInt value) { auto toArray = builder->array(); - RuntimeAssert(toArray->count_ >= 11 + position, "must be true"); + RuntimeAssert(toArray->count_ >= static_cast(11 + position), "must be true"); char cstring[12]; auto length = konan::snprintf(cstring, sizeof(cstring), "%d", value); RuntimeAssert(length >= 0, "This should never happen"); // may be overkill - RuntimeAssert(length < sizeof(cstring), "Unexpectedly large value"); // Can't be, but this is what sNprintf for + RuntimeAssert(static_cast(length) < sizeof(cstring), "Unexpectedly large value"); // Can't be, but this is what sNprintf for auto* from = &cstring[0]; auto* to = CharArrayAddressOfElementAt(toArray, position); while (*from) { @@ -951,7 +959,7 @@ KBoolean Kotlin_String_equalsIgnoreCase(KString thiz, KConstRef other) { auto count = thiz->count_; const KChar* thizRaw = CharArrayAddressOfElementAt(thiz, 0); const KChar* otherRaw = CharArrayAddressOfElementAt(otherString, 0); - for (KInt index = 0; index < count; ++index) { + for (uint32_t index = 0; index < count; ++index) { if (towlower_Konan(*thizRaw++) != towlower_Konan(*otherRaw++)) return false; } return true; @@ -1072,7 +1080,7 @@ KInt Kotlin_String_indexOfChar(KString thiz, KChar ch, KInt fromIndex) { if (fromIndex < 0) { fromIndex = 0; } - if (fromIndex > thiz->count_) { + if (static_cast(fromIndex) > thiz->count_) { return -1; } KInt count = thiz->count_; @@ -1088,7 +1096,7 @@ KInt Kotlin_String_lastIndexOfChar(KString thiz, KChar ch, KInt fromIndex) { if (fromIndex < 0 || thiz->count_ == 0) { return -1; } - if (fromIndex >= thiz->count_) { + if (static_cast(fromIndex) >= thiz->count_) { fromIndex = thiz->count_ - 1; } KInt index = fromIndex; @@ -1105,10 +1113,10 @@ KInt Kotlin_String_indexOfString(KString thiz, KString other, KInt fromIndex) { if (fromIndex < 0) { fromIndex = 0; } - if (fromIndex >= thiz->count_) { + if (static_cast(fromIndex) >= thiz->count_) { return (other->count_ == 0) ? thiz->count_ : -1; } - if (other->count_ > static_cast(thiz->count_) - fromIndex) { + if (static_cast(other->count_) > static_cast(thiz->count_) - fromIndex) { return -1; } // An empty string can be always found. diff --git a/runtime/src/main/cpp/Memory.cpp b/runtime/src/main/cpp/Memory.cpp index a830b922cc9..0a6967ff2cc 100644 --- a/runtime/src/main/cpp/Memory.cpp +++ b/runtime/src/main/cpp/Memory.cpp @@ -102,7 +102,7 @@ constexpr size_t kMaxToFreeSizeThreshold = 8 * 1024; // Never exceed this value when increasing size for toFree set, triggering actual cycle collector. constexpr size_t kMaxErgonomicToFreeSizeThreshold = 8 * 1024 * 1024; // How many elements in finalizer queue allowed before cleaning it up. -constexpr size_t kFinalizerQueueThreshold = 32; +constexpr int32_t kFinalizerQueueThreshold = 32; // If allocated that much memory since last GC - force new GC. constexpr size_t kMaxGcAllocThreshold = 8 * 1024 * 1024; // If the ratio of GC collection cycles time to program execution time is greater this value, @@ -848,7 +848,7 @@ inline void traverseObjectFields(ObjHeader* obj, func process) { } } else { ArrayHeader* array = obj->array(); - for (int index = 0; index < array->count_; index++) { + for (uint32_t index = 0; index < array->count_; index++) { process(ArrayAddressOfElementAt(array, index)); } } @@ -866,7 +866,7 @@ template inline void traverseContainerObjects(ContainerHeader* container, func process) { RuntimeAssert(!isAggregatingFrozenContainer(container), "Must not be called on such containers"); ObjHeader* obj = reinterpret_cast(container + 1); - for (int i = 0; i < container->objectCount(); ++i) { + for (uint32_t i = 0; i < container->objectCount(); ++i) { process(obj); obj = reinterpret_cast( reinterpret_cast(obj) + objectSize(obj)); @@ -1052,7 +1052,7 @@ void freeAggregatingFrozenContainer(ContainerHeader* container) { // Special container for frozen objects. ContainerHeader** subContainer = reinterpret_cast(container + 1); MEMORY_LOG("Total subcontainers = %d\n", container->objectCount()); - for (int i = 0; i < container->objectCount(); ++i) { + for (uint32_t i = 0; i < container->objectCount(); ++i) { MEMORY_LOG("Freeing subcontainer %p\n", *subContainer); freeContainer(*subContainer++); } @@ -1067,7 +1067,7 @@ void freeAggregatingFrozenContainer(ContainerHeader* container) { // so better be inlined. ALWAYS_INLINE void runDeallocationHooks(ContainerHeader* container) { ObjHeader* obj = reinterpret_cast(container + 1); - for (int index = 0; index < container->objectCount(); index++) { + for (uint32_t index = 0; index < container->objectCount(); index++) { auto* type_info = obj->type_info(); if (type_info == theWorkerBoundReferenceTypeInfo) { DisposeWorkerBoundReference(obj); @@ -1653,7 +1653,7 @@ inline ArenaContainer* initedArena(ObjHeader** auxSlot) { inline size_t containerSize(const ContainerHeader* container) { size_t result = 0; const ObjHeader* obj = reinterpret_cast(container + 1); - for (int object = 0; object < container->objectCount(); object++) { + for (uint32_t object = 0; object < container->objectCount(); object++) { size_t size = objectSize(obj); result += size; obj = reinterpret_cast(reinterpret_cast(obj) + size); @@ -1771,7 +1771,8 @@ void garbageCollect(MemoryState* state, bool force) { auto decrementStackDuration = konan::getTimeMicros() - decrementStackStartTime; GC_LOG("||| GC: decrementStackDuration = %lld\n", decrementStackDuration); #endif - long stackReferences = afterDecrements - beforeDecrements; + RuntimeAssert(afterDecrements >= beforeDecrements, "toRelease size must not have decreased"); + size_t stackReferences = afterDecrements - beforeDecrements; if (state->gcErgonomics && stackReferences * 5 > state->gcThreshold) { increaseGcThreshold(state); GC_LOG("||| GC: too many stack references, increased threshold to %d\n", state->gcThreshold); diff --git a/runtime/src/main/cpp/Natives.cpp b/runtime/src/main/cpp/Natives.cpp index e9fb15336f8..c0e339c5b66 100644 --- a/runtime/src/main/cpp/Natives.cpp +++ b/runtime/src/main/cpp/Natives.cpp @@ -14,11 +14,12 @@ * limitations under the License. */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include "KAssert.h" #include "Exceptions.h" @@ -49,7 +50,7 @@ OBJ_GETTER0(Kotlin_native_internal_undefined) { } void* Kotlin_interop_malloc(KLong size, KInt align) { - if (size > SIZE_MAX) { + if (size < 0 || static_cast::type>(size) > std::numeric_limits::max()) { return nullptr; } RuntimeAssert(align > 0, "Unsupported alignment"); diff --git a/runtime/src/main/cpp/ObjCExceptions.cpp b/runtime/src/main/cpp/ObjCExceptions.cpp index ca54e794263..a3c3ebdbec2 100644 --- a/runtime/src/main/cpp/ObjCExceptions.cpp +++ b/runtime/src/main/cpp/ObjCExceptions.cpp @@ -22,11 +22,11 @@ static void writeStackTraceToBuffer(KRef throwable, char* buffer, unsigned long *(bufferPointer++) = '('; --remainingBytes; - for (int index = 0; index < stackTrace->count_; ++index) { + for (uint32_t index = 0; index < stackTrace->count_; ++index) { KNativePtr ptr = *PrimitiveArrayAddressOfElementAt(stackTrace, index); int bytes = snprintf(bufferPointer, remainingBytes, "0x%" PRIxPTR " ", reinterpret_cast(ptr)); - if (bytes >= remainingBytes) { + if (bytes < 0 || static_cast(bytes) >= remainingBytes) { break; } @@ -122,4 +122,4 @@ void ReportBacktraceToIosCrashLog(KRef throwable) { writeStackTraceToBuffer(throwable, buffer, bufferSize); } -#endif // KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG \ No newline at end of file +#endif // KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG diff --git a/runtime/src/main/cpp/ObjCExport.mm b/runtime/src/main/cpp/ObjCExport.mm index f1b4df001e5..3eb82795b65 100644 --- a/runtime/src/main/cpp/ObjCExport.mm +++ b/runtime/src/main/cpp/ObjCExport.mm @@ -693,7 +693,7 @@ static const TypeInfo* createTypeInfo( } const TypeInfo** implementedInterfaces_ = konanAllocArray(implementedInterfaces.size()); - for (int i = 0; i < implementedInterfaces.size(); ++i) { + for (size_t i = 0; i < implementedInterfaces.size(); ++i) { implementedInterfaces_[i] = implementedInterfaces[i]; } @@ -709,7 +709,7 @@ static const TypeInfo* createTypeInfo( } MethodTableRecord* openMethods_ = konanAllocArray(methodTable.size()); - for (int i = 0; i < methodTable.size(); ++i) openMethods_[i] = methodTable[i]; + for (size_t i = 0; i < methodTable.size(); ++i) openMethods_[i] = methodTable[i]; result->openMethods_ = openMethods_; result->openMethodsCount_ = methodTable.size(); @@ -718,7 +718,7 @@ static const TypeInfo* createTypeInfo( result->relativeName_ = nullptr; // TODO: add some info. result->writableInfo_ = (WritableTypeInfo*)konanAllocMemory(sizeof(WritableTypeInfo)); - for (int i = 0; i < vtable.size(); ++i) result->vtable()[i] = vtable[i]; + for (size_t i = 0; i < vtable.size(); ++i) result->vtable()[i] = vtable[i]; return result; } @@ -727,7 +727,7 @@ static void addDefinedSelectors(Class clazz, KStdUnorderedSet& result) { unsigned int objcMethodCount; Method* objcMethods = class_copyMethodList(clazz, &objcMethodCount); - for (int i = 0; i < objcMethodCount; ++i) { + for (unsigned int i = 0; i < objcMethodCount; ++i) { result.insert(method_getName(objcMethods[i])); } @@ -895,7 +895,7 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co auto interfaceVTableIt = interfaceVTables.find(interfaceId); RuntimeAssert(interfaceVTableIt != interfaceVTables.end(), ""); auto& interfaceVTable = interfaceVTableIt->second; - RuntimeAssert(methodIndex >= 0 && methodIndex < interfaceVTable.size(), ""); + RuntimeAssert(methodIndex >= 0 && static_cast(methodIndex) < interfaceVTable.size(), ""); interfaceVTable[methodIndex] = entry; }; @@ -934,7 +934,7 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co interfaceVTables.emplace(interfaceId, KStdVector(interfaceVTableSize)); } else { auto const& interfaceVTable = interfaceVTablesIt->second; - RuntimeAssert(interfaceVTable.size() == interfaceVTableSize, ""); + RuntimeAssert(interfaceVTable.size() == static_cast(interfaceVTableSize), ""); } } diff --git a/runtime/src/main/cpp/Porting.cpp b/runtime/src/main/cpp/Porting.cpp index eae63ad353c..953c16cecdd 100644 --- a/runtime/src/main/cpp/Porting.cpp +++ b/runtime/src/main/cpp/Porting.cpp @@ -154,7 +154,7 @@ void consolePrintf(const char* format, ...) { va_start(args, format); int rv = vsnprintf_impl(buffer, sizeof(buffer), format, args); if (rv < 0) return; // TODO: this may be too much exotic, but should i try to print itoa(error) and terminate? - if (rv >= sizeof(buffer)) rv = sizeof(buffer) - 1; // TODO: Consider realloc or report truncating. + if (static_cast(rv) >= sizeof(buffer)) rv = sizeof(buffer) - 1; // TODO: Consider realloc or report truncating. va_end(args); consoleWriteUtf8(buffer, rv); } @@ -166,7 +166,7 @@ void consoleErrorf(const char* format, ...) { va_start(args, format); int rv = vsnprintf_impl(buffer, sizeof(buffer), format, args); if (rv < 0) return; // TODO: this may be too much exotic, but should i try to print itoa(error) and terminate? - if (rv >= sizeof(buffer)) rv = sizeof(buffer) - 1; // TODO: Consider realloc or report truncating. + if (static_cast(rv) >= sizeof(buffer)) rv = sizeof(buffer) - 1; // TODO: Consider realloc or report truncating. va_end(args); consoleErrorUtf8(buffer, rv); } @@ -451,7 +451,7 @@ extern "C" { 100000007UL, 1000000007UL }; - int table_length = sizeof(primes)/sizeof(unsigned long); + size_t table_length = sizeof(primes)/sizeof(unsigned long); if (n > primes[table_length - 1]) konan::abort(); @@ -490,7 +490,7 @@ extern "C" { #ifdef KONAN_WASM // Some string.h functions. void *memcpy(void *dst, const void *src, size_t n) { - for (long i = 0; i != n; ++i) + for (size_t i = 0; i != n; ++i) *((char*)dst + i) = *((char*)src + i); return dst; } @@ -507,7 +507,7 @@ extern "C" { } int memcmp(const void *s1, const void *s2, size_t n) { - for (long i = 0; i != n; ++i) { + for (size_t i = 0; i != n; ++i) { if (*((char*)s1 + i) != *((char*)s2 + i)) { return *((char*)s1 + i) - *((char*)s2 + i); } @@ -516,7 +516,7 @@ extern "C" { } void *memset(void *b, int c, size_t len) { - for (long i = 0; i != len; ++i) { + for (size_t i = 0; i != len; ++i) { *((char*)b + i) = c; } return b; @@ -529,7 +529,7 @@ extern "C" { } size_t strnlen(const char *s, size_t maxlen) { - for (long i = 0; i<=maxlen; ++i) { + for (size_t i = 0; i<=maxlen; ++i) { if (s[i] == 0) return i; } return maxlen; diff --git a/runtime/src/main/cpp/Regex.cpp b/runtime/src/main/cpp/Regex.cpp index 94a7858f2d9..b8371d7ed0a 100644 --- a/runtime/src/main/cpp/Regex.cpp +++ b/runtime/src/main/cpp/Regex.cpp @@ -607,7 +607,7 @@ KInt Kotlin_text_regex_decomposeString(ArrayHeader* inputCodePoints, KInt inputL KInt Kotlin_text_regex_decomposeCodePoint(KInt codePoint, ArrayHeader* outputCodePoints, KInt fromIndex) { RuntimeAssert(outputCodePoints->type_info() == theIntArrayTypeInfo, "Must be an Int array"); - RuntimeAssert(fromIndex >= 0 && fromIndex < outputCodePoints->count_, "Start index must be >= 0 and < array size"); + RuntimeAssert(fromIndex >= 0 && static_cast(fromIndex) < outputCodePoints->count_, "Start index must be >= 0 and < array size"); KInt* rawResult = IntArrayAddressOfElementAt(outputCodePoints, fromIndex); const Decomposition* decomposition = getDecomposition(codePoint); if (decomposition == nullptr) { diff --git a/runtime/src/main/cpp/Worker.cpp b/runtime/src/main/cpp/Worker.cpp index b9f58b9b199..830c490ca2a 100644 --- a/runtime/src/main/cpp/Worker.cpp +++ b/runtime/src/main/cpp/Worker.cpp @@ -93,7 +93,7 @@ struct Job { struct { KNativePtr operation; - KLong whenExecute; + uint64_t whenExecute; } executeAfter; }; }; @@ -339,6 +339,8 @@ class State { Worker* worker = nullptr; Locker locker(&lock_); + RuntimeAssert(afterMicroseconds >= 0, "afterMicroseconds cannot be negative"); + auto it = workers_.find(id); if (it == workers_.end()) { return false; diff --git a/runtime/src/main/cpp/dlmalloc/malloc.cpp b/runtime/src/main/cpp/dlmalloc/malloc.cpp index 35f4f3cce66..4cccd167fa7 100644 --- a/runtime/src/main/cpp/dlmalloc/malloc.cpp +++ b/runtime/src/main/cpp/dlmalloc/malloc.cpp @@ -1,3 +1,5 @@ +// Uses GNU extension on null pointer arithmetic. +#pragma clang diagnostic ignored "-Wnull-pointer-arithmetic" /* This is a version (aka dlmalloc) of malloc/free/realloc written by Doug Lea and released to the public domain, as explained at diff --git a/runtime/src/objc/cpp/ObjCExportCollections.mm b/runtime/src/objc/cpp/ObjCExportCollections.mm index 50f400f1322..6e01c23eab4 100644 --- a/runtime/src/objc/cpp/ObjCExportCollections.mm +++ b/runtime/src/objc/cpp/ObjCExportCollections.mm @@ -69,7 +69,7 @@ void Kotlin_MutableList_setObject(KRef list, KInt index, KRef obj); } // extern "C" static inline KInt objCCapacityToKotlin(NSUInteger capacity) { - KInt max = std::numeric_limits::max(); + NSUInteger max = std::numeric_limits::max(); return capacity > max ? max : capacity; }