Test for negative array length. (#2710)
This commit is contained in:
+7
-7
@@ -402,17 +402,17 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun allocInstance(typeInfo: LLVMValueRef, lifetime: Lifetime): LLVMValueRef {
|
fun allocInstance(typeInfo: LLVMValueRef, lifetime: Lifetime): LLVMValueRef =
|
||||||
return call(context.llvm.allocInstanceFunction, listOf(typeInfo), lifetime)
|
call(context.llvm.allocInstanceFunction, listOf(typeInfo), lifetime)
|
||||||
}
|
|
||||||
|
|
||||||
fun allocInstance(irClass: IrClass, lifetime: Lifetime): LLVMValueRef =
|
fun allocInstance(irClass: IrClass, lifetime: Lifetime): LLVMValueRef =
|
||||||
allocInstance(codegen.typeInfoForAllocation(irClass), lifetime)
|
allocInstance(codegen.typeInfoForAllocation(irClass), lifetime)
|
||||||
|
|
||||||
fun allocArray(
|
fun allocArray(typeInfo: LLVMValueRef,
|
||||||
typeInfo: LLVMValueRef, count: LLVMValueRef, lifetime: Lifetime): LLVMValueRef {
|
count: LLVMValueRef,
|
||||||
return call(context.llvm.allocArrayFunction, listOf(typeInfo, count), lifetime)
|
lifetime: Lifetime,
|
||||||
}
|
exceptionHandler: ExceptionHandler): LLVMValueRef =
|
||||||
|
call(context.llvm.allocArrayFunction, listOf(typeInfo, count), lifetime, exceptionHandler)
|
||||||
|
|
||||||
fun unreachable(): LLVMValueRef? {
|
fun unreachable(): LLVMValueRef? {
|
||||||
val res = LLVMBuildUnreachable(builder)
|
val res = LLVMBuildUnreachable(builder)
|
||||||
|
|||||||
+2
-2
@@ -2062,12 +2062,12 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
val thisValue = if (constructedClass.isArray) {
|
val thisValue = if (constructedClass.isArray) {
|
||||||
assert(args.isNotEmpty() && args[0].type == int32Type)
|
assert(args.isNotEmpty() && args[0].type == int32Type)
|
||||||
functionGenerationContext.allocArray(codegen.typeInfoValue(constructedClass), args[0],
|
functionGenerationContext.allocArray(codegen.typeInfoValue(constructedClass), args[0],
|
||||||
resultLifetime(callee))
|
resultLifetime(callee), currentCodeContext.exceptionHandler)
|
||||||
} else if (constructedClass == context.ir.symbols.string.owner) {
|
} else if (constructedClass == context.ir.symbols.string.owner) {
|
||||||
// TODO: consider returning the empty string literal instead.
|
// TODO: consider returning the empty string literal instead.
|
||||||
assert(args.isEmpty())
|
assert(args.isEmpty())
|
||||||
functionGenerationContext.allocArray(codegen.typeInfoValue(constructedClass), count = kImmZero,
|
functionGenerationContext.allocArray(codegen.typeInfoValue(constructedClass), count = kImmZero,
|
||||||
lifetime = resultLifetime(callee))
|
lifetime = resultLifetime(callee), exceptionHandler = currentCodeContext.exceptionHandler)
|
||||||
} else if (constructedClass.isObjCClass()) {
|
} else if (constructedClass.isObjCClass()) {
|
||||||
assert(constructedClass.isKotlinObjCClass()) // Calls to other ObjC class constructors must be lowered.
|
assert(constructedClass.isKotlinObjCClass()) // Calls to other ObjC class constructors must be lowered.
|
||||||
val symbols = context.ir.symbols
|
val symbols = context.ir.symbols
|
||||||
|
|||||||
@@ -1593,6 +1593,12 @@ task array3(type: RunKonanTest) {
|
|||||||
source = "runtime/collections/array3.kt"
|
source = "runtime/collections/array3.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task array4(type: RunKonanTest) {
|
||||||
|
disabled = (project.testTarget == 'wasm32') // Uses exceptions.
|
||||||
|
goldValue = "OK\n"
|
||||||
|
source = "runtime/collections/array4.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task typed_array0(type: RunKonanTest) {
|
task typed_array0(type: RunKonanTest) {
|
||||||
goldValue = "OK\n"
|
goldValue = "OK\n"
|
||||||
source = "runtime/collections/typed_array0.kt"
|
source = "runtime/collections/typed_array0.kt"
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.array4
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
@Test fun runTest() {
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = Array(-2) { "nope" }
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = ByteArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = UByteArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = ShortArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = UShortArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = IntArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = UIntArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = LongArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = ULongArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = FloatArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = DoubleArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = BooleanArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val a = CharArray(-2)
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
|
println("OK")
|
||||||
|
}
|
||||||
@@ -1282,8 +1282,9 @@ OBJ_GETTER(AllocInstance, const TypeInfo* type_info) {
|
|||||||
RETURN_OBJ(ObjectContainer(type_info).GetPlace());
|
RETURN_OBJ(ObjectContainer(type_info).GetPlace());
|
||||||
}
|
}
|
||||||
|
|
||||||
OBJ_GETTER(AllocArrayInstance, const TypeInfo* type_info, uint32_t elements) {
|
OBJ_GETTER(AllocArrayInstance, const TypeInfo* type_info, int32_t elements) {
|
||||||
RuntimeAssert(type_info->instanceSize_ < 0, "must be an array");
|
RuntimeAssert(type_info->instanceSize_ < 0, "must be an array");
|
||||||
|
if (elements < 0) ThrowIllegalArgumentException();
|
||||||
if (isArenaSlot(OBJ_RESULT)) {
|
if (isArenaSlot(OBJ_RESULT)) {
|
||||||
auto arena = initedArena(asArenaSlot(OBJ_RESULT));
|
auto arena = initedArena(asArenaSlot(OBJ_RESULT));
|
||||||
auto result = arena->PlaceArray(type_info, elements)->obj();
|
auto result = arena->PlaceArray(type_info, elements)->obj();
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ void ResumeMemory(MemoryState* state);
|
|||||||
// selection, and comes from upper bound esteemation of object lifetime.
|
// selection, and comes from upper bound esteemation of object lifetime.
|
||||||
//
|
//
|
||||||
OBJ_GETTER(AllocInstance, const TypeInfo* type_info) RUNTIME_NOTHROW;
|
OBJ_GETTER(AllocInstance, const TypeInfo* type_info) RUNTIME_NOTHROW;
|
||||||
OBJ_GETTER(AllocArrayInstance, const TypeInfo* type_info, uint32_t elements) RUNTIME_NOTHROW;
|
OBJ_GETTER(AllocArrayInstance, const TypeInfo* type_info, int32_t elements);
|
||||||
void DeinitInstanceBody(const TypeInfo* typeInfo, void* body);
|
void DeinitInstanceBody(const TypeInfo* typeInfo, void* body);
|
||||||
OBJ_GETTER(InitInstance, ObjHeader** location, const TypeInfo* type_info,
|
OBJ_GETTER(InitInstance, ObjHeader** location, const TypeInfo* type_info,
|
||||||
void (*ctor)(ObjHeader*));
|
void (*ctor)(ObjHeader*));
|
||||||
|
|||||||
Reference in New Issue
Block a user