[K/N][Tests] Move filecheck and cinterop tests to /native/

^KT-61259
This commit is contained in:
Vladimir Sukharev
2024-02-14 13:07:40 +01:00
committed by Space Team
parent 05cbe66ee0
commit bf0150108d
144 changed files with 1683 additions and 5542 deletions
@@ -0,0 +1,34 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: carrayPointers.def
---
int (*arrayPointer)[1];
int globalArray[3] = {1, 2, 3};
struct StructWithArrayPtr {
int (*arrayPointer)[1];
};
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import carrayPointers.*
import kotlin.test.*
import kotlinx.cinterop.*
fun box(): String {
arrayPointer = globalArray
assertEquals(globalArray[0], arrayPointer!![0])
arrayPointer!![0] = 15
assertEquals(15, globalArray[0])
memScoped {
val struct = alloc<StructWithArrayPtr>()
struct.arrayPointer = globalArray
assertEquals(globalArray[0], struct.arrayPointer!![0])
}
return "OK"
}
@@ -0,0 +1,41 @@
// TARGET_BACKEND: NATIVE
// FREE_CINTEROP_ARGS: -header auxiliaryCppSources.h
// MODULE: cinterop
// FILE: auxiliaryCppSources.def
# The def file is intentionally empty
# `auxiliaryCppSources.h` is meant to be included via `-header` free arg of cinterop tool
// FILE: auxiliaryCppSources.h
#ifdef __cplusplus
extern "C" {
#endif
const char* name();
#ifdef __cplusplus
}
#endif
// FILE: auxiliaryCppSources.cpp
#include <string>
#include "auxiliaryCppSources.h"
static std::string _name = "OK";
extern "C" const char* name() {
return _name.c_str();
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import auxiliaryCppSources.*
import kotlin.test.*
import kotlinx.cinterop.*
fun box(): String {
return name()!!.toKString()
}
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2023 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cstdlib.def
headers = stdlib.h
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import cstdlib.*
import kotlinx.cinterop.*
import kotlin.test.*
fun box(): String {
assertEquals(257, atoi("257"))
val divResult = div(-5, 3)
val (quot, rem) = divResult.useContents { Pair(quot, rem) }
assertEquals(-1, quot)
assertEquals(-2, rem)
return "OK"
}
@@ -0,0 +1,36 @@
/*
* Copyright 2010-2023 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cstdlib.def
headers = stdlib.h
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import cstdlib.*
import kotlinx.cinterop.*
import kotlin.test.*
fun box(): String {
val values = intArrayOf(14, 12, 9, 13, 8)
val count = values.size
qsort(values.refTo(0), count.convert(), IntVar.size.convert(), staticCFunction { a, b ->
val aValue = a!!.reinterpret<IntVar>()[0]
val bValue = b!!.reinterpret<IntVar>()[0]
(aValue - bValue)
})
assertEquals(8, values[0])
assertEquals(9, values[1])
assertEquals(12, values[2])
assertEquals(13, values[3])
assertEquals(14, values[4])
return "OK"
}
@@ -0,0 +1,75 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cstdlib.def
headers = stdlib.h processor_count.h
compilerOpts.mingw = -D ADD_WINDOWS_ENV_FUNCTIONS
---
#ifdef ADD_WINDOWS_ENV_FUNCTIONS
static inline int setenv(const char *name, const char *value, int overwrite)
{
int errcode = 0;
if (!overwrite) {
size_t envsize = 0;
errcode = getenv_s(&envsize, NULL, 0, name);
if(errcode || envsize) return errcode;
}
return _putenv_s(name, value);
}
static inline int unsetenv(const char *name)
{
return _putenv_s(name, "");
}
#endif
// FILE: processor_count.h
int availableProcessors();
// FILE: processor_count.cpp
#include <thread>
extern "C" {
#include "processor_count.h"
int availableProcessors () { return std::thread::hardware_concurrency(); }
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalNativeApi::class)
import kotlin.native.*
import kotlin.test.*
import cstdlib.*
import kotlinx.cinterop.*
@OptIn(kotlin.ExperimentalStdlibApi::class)
fun box(): String {
val platformProcessors: Int = Platform.getAvailableProcessors()
assertTrue(platformProcessors > 0)
assertEquals(availableProcessors(), platformProcessors)
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", "12345", 1)
assertEquals(Platform.getAvailableProcessors(), 12345)
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", Long.MAX_VALUE.toString(), 1)
assertFailsWith<IllegalStateException> { Platform.getAvailableProcessors() }
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", "-1", 1)
assertFailsWith<IllegalStateException> { Platform.getAvailableProcessors() }
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", "0", 1)
assertFailsWith<IllegalStateException> { Platform.getAvailableProcessors() }
// windows doesn't support empty env variables
if (Platform.osFamily != OsFamily.WINDOWS) {
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", "", 1)
assertFailsWith<IllegalStateException> { Platform.getAvailableProcessors() }
}
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", "123aaaa", 1)
assertFailsWith<IllegalStateException> { Platform.getAvailableProcessors() }
unsetenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS")
assertEquals(Platform.getAvailableProcessors(), platformProcessors)
return "OK"
}
@@ -0,0 +1,151 @@
/*
* Copyright 2010-2023 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cmacros.def
excludedMacros = EXCLUDED
---
int* ptr_call() {
return (int*) 1;
}
int int_call() {
return 42;
}
void void_call() {}
int arg_call(int x) {
return x;
}
typedef struct {
int value
} struct_t;
struct_t getStruct() {
return (struct_t){ 1 };
}
int global_var = 5;
#define TOO_MANY_ERRORS x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x
#define LEFT_BRACE {
#define ZERO 0
#define ONE 1
#define RIGHT_BRACE }
#define MAX_LONG 9223372036854775807
#define FOO_STRING "foo"
// This one should be ignored:
#define WIDE_FOO_STRING L"foo"
#define FOURTY_TWO 42
#define SEVENTEEN ((long long) 17)
#define ONE_POINT_ZERO 1.0
#define ONE_POINT_FIVE 1.5f
#define LEFT_PAREN (
#define NULL_PTR ((void*)0)
#define VOID_PTR ((void*)1)
#define INT_PTR ((int*)1)
#define PTR_SUM (INT_PTR + 1)
#define PTR_SUM_EXPECTED (sizeof(int) + 1)
#define RIGHT_PAREN )
enum {
INT_CALL = 1 // Should be replaced by macro below.
};
#define PTR_CALL ptr_call()
#define INT_CALL int_call()
#define CALL_SUM (int_call() + int_call())
#define GLOBAL_VAR (global_var)
// This one should be excluded:
#define EXCLUDED 42
// These ones should be ignored:
#define VOID_CALL (void_call())
#define ARG_CALL(x) (arg_call(x))
#define GET_STRUCT (getStruct())
#define UNDECLARED (undeclared())
#define BAD1 bar
#define BAD2 5;
#define BAD3 { foo(); }
void increment(int* counter);
#define increment(counter) { (*(counter))++; }
#define DEFAULT_DOUBLE_NAN __builtin_nan("")
#define DEFAULT_FLOAT_NAN __builtin_nanf("")
#define OTHER_DOUBLE_NAN __builtin_nan("0x123456789ab")
#define OTHER_FLOAT_NAN __builtin_nanf("0x12345")
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.experimental.ExperimentalNativeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.test.*
import cmacros.*
import kotlinx.cinterop.*
fun box(): String {
assertEquals("foo", FOO_STRING)
assertEquals(0, ZERO)
assertEquals(1, ONE)
assertEquals(Long.MAX_VALUE, MAX_LONG)
assertEquals(42, FOURTY_TWO)
val seventeen: Long = SEVENTEEN
assertEquals(17L, seventeen)
val onePointFive: Float = ONE_POINT_FIVE
val onePointZero: Double = ONE_POINT_ZERO
assertEquals(1.5f, onePointFive)
assertEquals(1.0, onePointZero)
val nullPtr: COpaquePointer? = NULL_PTR
val voidPtr: COpaquePointer? = VOID_PTR
val intPtr: CPointer<IntVar>? = INT_PTR
val ptrSum: CPointer<IntVar>? = PTR_SUM
val ptrCall: CPointer<IntVar>? = PTR_CALL
assertEquals(null, nullPtr)
assertEquals(1L, voidPtr.rawValue.toLong())
assertEquals(1L, intPtr.rawValue.toLong())
assertEquals(PTR_SUM_EXPECTED.toLong(), ptrSum.rawValue.toLong())
assertEquals(1L, ptrCall.rawValue.toLong())
assertEquals(42, INT_CALL)
assertEquals(84, CALL_SUM)
assertEquals(5, GLOBAL_VAR)
memScoped {
val counter = alloc<IntVar>()
counter.value = 42
increment(counter.ptr)
assertEquals(43, counter.value)
}
val floatNanBase = Float.NaN.toRawBits()
assertEquals(floatNanBase, 0x7fc00000)
val doubleNanBase = Double.NaN.toRawBits()
assertEquals(doubleNanBase, 0x7ff8000000000000L)
assertEquals(floatNanBase, DEFAULT_FLOAT_NAN.toRawBits())
assertEquals(doubleNanBase, DEFAULT_DOUBLE_NAN.toRawBits())
assertEquals(floatNanBase, OTHER_FLOAT_NAN.toRawBits())
assertEquals(doubleNanBase, OTHER_DOUBLE_NAN.toRawBits())
return "OK"
}
@@ -0,0 +1,24 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: mangling.def
---
// test mangling of special names
enum _Companion {Companion, Any};
enum _Companion companion = Companion;
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.test.*
import mangling.*
fun box(): String {
companion = _Companion.`Companion$`
assertEquals(_Companion.`Companion$`, companion)
return "OK"
}
@@ -0,0 +1,23 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: mangling2.def
---
// test mangling of special names
enum Companion {One, Two};
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.test.*
import mangling2.*
fun box(): String {
val mangled = `Companion$`.Two
assertEquals(`Companion$`.Two, mangled)
return "OK"
}
@@ -0,0 +1,55 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: mangling_keywords.def
---
#define as "as"
#define class "class"
#define dynamic "dynamic"
#define false "false"
#define fun "fun"
#define in "in"
#define interface "interface"
#define is "is"
#define null "null"
#define object "object"
#define package "package"
#define super "super"
#define this "this"
#define throw "throw"
#define true "true"
#define try "try"
#define typealias "typealias"
#define val "val"
#define var "var"
#define when "when"
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.test.*
import mangling_keywords.*
fun box(): String {
// Check that all Kotlin keywords are imported and mangled.
assertEquals("as", `as`)
assertEquals("class", `class`)
assertEquals("dynamic", `dynamic`)
assertEquals("false", `false`)
assertEquals("fun", `fun`)
assertEquals("in", `in`)
assertEquals("interface", `interface`)
assertEquals("is", `is`)
assertEquals("null", `null`)
assertEquals("object", `object`)
assertEquals("package", `package`)
assertEquals("super", `super`)
assertEquals("this", `this`)
assertEquals("throw", `throw`)
assertEquals("true", `true`)
assertEquals("try", `try`)
assertEquals("typealias", `typealias`)
assertEquals("val", `val`)
assertEquals("var", `var`)
assertEquals("when", `when`)
return "OK"
}
@@ -0,0 +1,131 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: mangling_keywords2.def
---
enum KotlinKeywordsEnum {
as,
class,
dynamic,
false,
fun,
in,
interface,
is,
null,
object,
package,
super,
this,
throw,
true,
try,
typealias,
val,
var,
when,
};
struct KotlinKeywordsStruct {
int as;
int class;
int dynamic;
int false;
int fun;
int in;
int interface;
int is;
int null;
int object;
int package;
int super;
int this;
int throw;
int true;
int try;
int typealias;
int val;
int var;
int when;
};
struct KotlinKeywordsStruct createKotlinKeywordsStruct() {
struct KotlinKeywordsStruct s = {
.as = 0,
.class = 0,
.dynamic = 0,
.false = 0,
.fun = 0,
.in = 0,
.interface = 0,
.is = 0,
.null = 0,
.object = 0,
.package = 0,
.super = 0,
.this = 0,
.throw = 0,
.true = 0,
.try = 0,
.typealias = 0,
.val = 0,
.var = 0,
.when = 0,
};
return s;
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.test.*
import mangling_keywords2.*
import kotlinx.cinterop.useContents
fun box(): String {
// Check that all Kotlin keywords are imported and mangled.
createKotlinKeywordsStruct().useContents {
assertEquals(0, `as`)
assertEquals(0, `class`)
assertEquals(0, `dynamic`)
assertEquals(0, `false`)
assertEquals(0, `fun`)
assertEquals(0, `in`)
assertEquals(0, `interface`)
assertEquals(0, `is`)
assertEquals(0, `null`)
assertEquals(0, `object`)
assertEquals(0, `package`)
assertEquals(0, `super`)
assertEquals(0, `this`)
assertEquals(0, `throw`)
assertEquals(0, `true`)
assertEquals(0, `try`)
assertEquals(0, `typealias`)
assertEquals(0, `val`)
assertEquals(0, `var`)
assertEquals(0, `when`)
}
assertEquals(KotlinKeywordsEnum.`as`, KotlinKeywordsEnum.`as`)
assertEquals(KotlinKeywordsEnum.`class`, KotlinKeywordsEnum.`class`)
assertEquals(KotlinKeywordsEnum.`dynamic`, KotlinKeywordsEnum.`dynamic`)
assertEquals(KotlinKeywordsEnum.`false`, KotlinKeywordsEnum.`false`)
assertEquals(KotlinKeywordsEnum.`fun`, KotlinKeywordsEnum.`fun`)
assertEquals(KotlinKeywordsEnum.`in`, KotlinKeywordsEnum.`in`)
assertEquals(KotlinKeywordsEnum.`interface`, KotlinKeywordsEnum.`interface`)
assertEquals(KotlinKeywordsEnum.`is`, KotlinKeywordsEnum.`is`)
assertEquals(KotlinKeywordsEnum.`null`, KotlinKeywordsEnum.`null`)
assertEquals(KotlinKeywordsEnum.`object`, KotlinKeywordsEnum.`object`)
assertEquals(KotlinKeywordsEnum.`package`, KotlinKeywordsEnum.`package`)
assertEquals(KotlinKeywordsEnum.`super`, KotlinKeywordsEnum.`super`)
assertEquals(KotlinKeywordsEnum.`this`, KotlinKeywordsEnum.`this`)
assertEquals(KotlinKeywordsEnum.`throw`, KotlinKeywordsEnum.`throw`)
assertEquals(KotlinKeywordsEnum.`true`, KotlinKeywordsEnum.`true`)
assertEquals(KotlinKeywordsEnum.`try`, KotlinKeywordsEnum.`try`)
assertEquals(KotlinKeywordsEnum.`typealias`, KotlinKeywordsEnum.`typealias`)
assertEquals(KotlinKeywordsEnum.`val`, KotlinKeywordsEnum.`val`)
assertEquals(KotlinKeywordsEnum.`var`, KotlinKeywordsEnum.`var`)
assertEquals(KotlinKeywordsEnum.`when`, KotlinKeywordsEnum.`when`)
return "OK"
}
@@ -0,0 +1,25 @@
/*
* Copyright 2010-2023 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.
*/
// TARGET_BACKEND: NATIVE
// IGNORE_NATIVE: target=linux_arm64
// MODULE: cinterop
// FILE: sysstat.def
headers = sys/stat.h
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import sysstat.*
import kotlin.test.*
import kotlinx.cinterop.*
fun box(): String {
val statBuf = nativeHeap.alloc<stat>()
assertEquals(0, stat("/", statBuf.ptr))
assertEquals("0", statBuf.st_uid.toString())
return "OK"
}
@@ -0,0 +1,51 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: structAnonym.def
---
/*
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
*/
#include <inttypes.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winitializer-overrides"
struct StructAnonRecordMember_ExplicitAlignment {
char a;
struct {
__attribute__((aligned(4)))
char x;
};
};
static struct StructAnonRecordMember_ExplicitAlignment retByValue_StructAnonRecordMember_ExplicitAlignment() {
struct StructAnonRecordMember_ExplicitAlignment t = {
.a = 'a',
.x = 'x'
};
return t;
}
#pragma clang diagnostic pop
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.test.*
import structAnonym.*
fun box(): String {
retByValue_StructAnonRecordMember_ExplicitAlignment()
.useContents {
assertEquals('a', a.toInt().toChar())
assertEquals('x', x.toInt().toChar())
}
return "OK"
}
@@ -0,0 +1,52 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: structAnonym.def
---
/*
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
*/
#include <inttypes.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winitializer-overrides"
// trivial alignment: member is already aligned, but this implies implicit larger alignment of the root struct
struct StructAnonRecordMember_ImplicitAlignment {
int32_t a[4];
struct {
int b __attribute__((aligned(16)));
};
};
static struct StructAnonRecordMember_ImplicitAlignment retByValue_StructAnonRecordMember_ImplicitAlignment() {
struct StructAnonRecordMember_ImplicitAlignment t = {
.a = {1,2,3,4},
.b = 42
};
return t;
}
#pragma clang diagnostic pop
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.test.*
import structAnonym.*
fun box(): String {
retByValue_StructAnonRecordMember_ImplicitAlignment()
.useContents {
assertEquals(1, a[0])
assertEquals(4, a[3])
assertEquals(42, b)
}
return "OK"
}
@@ -0,0 +1,68 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: structAnonym.def
---
/*
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
*/
#include <inttypes.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winitializer-overrides"
// Deep nesting
struct StructAnonRecordMember_Nested {
int x;
union { // implicitly aligned to 8 bytes due to int64, or 4 bytes at 32-bit arch
int a[2];
struct {
int64_t b;
};
};
char z;
double y;
};
static struct StructAnonRecordMember_Nested retByValue_StructAnonRecordMember_Nested() {
struct StructAnonRecordMember_Nested c = {
.x = 37,
.b = 42,
.z = 'z',
.y = 3.14
};
return c;
}
static int sendByValue_StructAnonRecordMember_Nested(struct StructAnonRecordMember_Nested c) {
return c.a[0] + 2 * c.a[1];
}
#pragma clang diagnostic pop
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.test.*
import structAnonym.*
fun box(): String {
retByValue_StructAnonRecordMember_Nested()
.useContents {
assertEquals(37, x)
assertEquals(42, b)
assertEquals('z', z.toInt().toChar())
assertEquals(3.14, y)
a[0] = 3
a[1] = 5
assertEquals(3 + 2*5, sendByValue_StructAnonRecordMember_Nested(this.readValue()))
}
return "OK"
}
@@ -0,0 +1,74 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: structAnonym.def
---
/*
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
*/
#include <inttypes.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winitializer-overrides"
// Basic, 2 levels
struct StructAnonRecordMember_Complicate {
char first; // __attribute__((aligned(16)));
union {
int a[2];
union { char c1; int c2; };
struct { char b1; int64_t b2; }; // implicit 64-bits alignment
};
char second __attribute__((aligned(16)));
struct {
char x;
struct { int64_t b11, b12; } Y2;
int32_t f __attribute__((aligned(16)));
}; // __attribute__((aligned(16)));
char last;
};
#define INIT(T, x) struct T x = \
{ \
.first = 'a', \
.b1 = 'b', \
.b2 = 42, \
.second = 's', \
.last = 'z', \
.f = 314, \
.Y2 = {11, 12} \
}
static struct StructAnonRecordMember_Complicate retByValue_StructAnonRecordMember_Complicate() {
INIT(StructAnonRecordMember_Complicate, c);
return c;
}
#pragma clang diagnostic pop
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.test.*
import structAnonym.*
fun box(): String {
retByValue_StructAnonRecordMember_Complicate()
.useContents{
assertEquals('a', first.toInt().toChar())
assertEquals('s', second.toInt().toChar())
assertEquals('z', last.toInt().toChar())
assertEquals('b', b1.toInt().toChar())
assertEquals(42L, b2)
assertEquals(314, f)
assertEquals(11L, Y2.b11)
}
return "OK"
}
@@ -0,0 +1,63 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: structAnonym.def
---
/*
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
*/
#include <inttypes.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winitializer-overrides"
union _GLKVector3
{
struct { float x, y, z; };
struct { float r, g, b; };
struct { float s, t, p; };
float v[3];
};
static union _GLKVector3 get_GLKVector3() {
union _GLKVector3 ret = {{1, 2, 3}};
return ret;
}
static float hash_GLKVector3(union _GLKVector3 x) {
union _GLKVector3 ret = {{1, 2, 3}};
return x.x + 2.0f * x.y + 4.0f * x.z;
}
#pragma clang diagnostic pop
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.test.*
import structAnonym.*
fun box(): String {
get_GLKVector3().useContents {
assertEquals(1.0f, x)
assertEquals(2.0f, g)
assertEquals(3.0f, p)
r = 0.1f
g = 0.2f
b = 0.3f
assertEquals(v[0], r)
assertEquals(v[1], g)
assertEquals(v[2], b)
val ret = hash_GLKVector3(this.readValue())
assertEquals(s + 2f * t + 4f * p , ret)
}
return "OK"
}
@@ -0,0 +1,75 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: structAnonym.def
---
/*
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
*/
#include <inttypes.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winitializer-overrides"
#pragma pack(2)
struct StructAnonRecordMember_Packed2 {
char first;
union {
int a[2];
union { char c1; int c2; };
struct { char b1; int64_t b2; };
};
char second;
struct {
char x;
struct { int64_t b11, b12; } Y2;
int32_t f;
} __attribute__((aligned(16)));
char last;
} __attribute__ ((packed));
#pragma pack()
#define INIT(T, x) struct T x = \
{ \
.first = 'a', \
.b1 = 'b', \
.b2 = 42, \
.second = 's', \
.last = 'z', \
.f = 314, \
.Y2 = {11, 12} \
}
static struct StructAnonRecordMember_Packed2 retByValue_StructAnonRecordMember_Packed2() {
INIT(StructAnonRecordMember_Packed2, c);
return c;
}
#pragma clang diagnostic pop
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.test.*
import structAnonym.*
fun box(): String {
retByValue_StructAnonRecordMember_Packed2()
.useContents{
assertEquals('a', first.toInt().toChar())
assertEquals('s', second.toInt().toChar())
assertEquals('z', last.toInt().toChar())
assertEquals('b', b1.toInt().toChar())
assertEquals(42L, b2)
assertEquals(314, f)
assertEquals(11L, Y2.b11)
}
return "OK"
}
@@ -0,0 +1,76 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: structAnonym.def
---
/*
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
*/
#include <inttypes.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winitializer-overrides"
// Nested struct may be packed too
#pragma pack(2)
struct StructAnonRecordMember_Packed2 {
char first;
union {
int a[2];
union { char c1; int c2; };
struct { char b1; int64_t b2; };
};
char second;
struct {
char x;
struct { int64_t b11, b12; } Y2;
int32_t f;
} __attribute__((aligned(16)));
char last;
} __attribute__ ((packed));
#pragma pack()
#define INIT(T, x) struct T x = \
{ \
.first = 'a', \
.b1 = 'b', \
.b2 = 42, \
.second = 's', \
.last = 'z', \
.f = 314, \
.Y2 = {11, 12} \
}
static struct StructAnonRecordMember_Packed2 retByValue_StructAnonRecordMember_Packed2() {
INIT(StructAnonRecordMember_Packed2, c);
return c;
}
#pragma clang diagnostic pop
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.test.*
import structAnonym.*
fun box(): String {
retByValue_StructAnonRecordMember_Packed2()
.useContents{
assertEquals('a', first.toInt().toChar())
assertEquals('s', second.toInt().toChar())
assertEquals('z', last.toInt().toChar())
assertEquals('b', b1.toInt().toChar())
assertEquals(42L, b2)
assertEquals(314, f)
assertEquals(11L, Y2.b11)
}
return "OK"
}
@@ -0,0 +1,75 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: structAnonym.def
---
/*
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
*/
#include <inttypes.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winitializer-overrides"
// Nested struct may be packed too
#pragma pack(1)
struct StructAnonRecordMember_PragmaPacked {
char first;
union {
int a[2];
union { char c1; int c2; };
struct { char b1; int64_t b2; };
};
char second;
struct {
char x;
struct { int64_t b11, b12; } Y2;
int32_t f __attribute__((aligned(16))); // another kind of alignment
};
char last;
} __attribute__ ((packed));
#pragma pack()
#define INIT(T, x) struct T x = \
{ \
.first = 'a', \
.b1 = 'b', \
.b2 = 42, \
.second = 's', \
.last = 'z', \
.f = 314, \
.Y2 = {11, 12} \
}
static struct StructAnonRecordMember_PragmaPacked retByValue_StructAnonRecordMember_PragmaPacked() {
INIT(StructAnonRecordMember_PragmaPacked, c);
return c;
}
#pragma clang diagnostic pop
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.test.*
import structAnonym.*
fun box(): String {
retByValue_StructAnonRecordMember_PragmaPacked()
.useContents{
assertEquals('a', first.toInt().toChar())
assertEquals('s', second.toInt().toChar())
assertEquals('z', last.toInt().toChar())
assertEquals('b', b1.toInt().toChar())
assertEquals(42L, b2)
assertEquals(314, f)
assertEquals(11L, Y2.b11)
}
return "OK"
}
@@ -0,0 +1,193 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cstructs.def
nonStrictEnums = NonStrict
---
typedef struct {
int i;
} Trivial;
enum E {
R, G, B
};
enum NonStrict {
N, S, K
};
struct Complex {
unsigned int ui;
Trivial t;
struct Complex* next;
enum E e;
enum NonStrict nonStrict;
int arr[2];
_Bool b;
};
struct __attribute__((packed)) Packed {
int i : 1;
enum E e : 2;
};
struct Complex produceComplex() {
struct Complex complex = {
.ui = 128,
.t = {1},
.next = 0,
.e = R,
.nonStrict = K,
.arr = {-51, -19},
.b = 1
};
return complex;
};
struct WithFlexibleArray {
int size;
int data[];
};
struct WithFlexibleArrayWithPadding {
int size;
char c;
long long data[];
};
void fillArray(struct WithFlexibleArrayWithPadding *flex, int count) {
flex->size = count;
flex->c = '!';
for (int i = 0; i < count; i++) {
flex->data[i] = (((long long)i) << 32) | (i * 100);
}
}
struct WithZeroSizedArray {
int size;
int data[0];
};
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import cstructs.*
import kotlinx.cinterop.*
import kotlin.test.*
fun box(): String {
produceComplex().useContents {
assertEquals(ui, 128u)
ui = 333u
assertEquals(ui, 333u)
assertEquals(t.i, 1)
t.i += 15
assertEquals(t.i, 16)
assertEquals(next, null)
next = this.ptr
assertEquals(next, this.ptr)
// Check null pointer because it has Nothing? type.
next = null
assertEquals(next, null)
assertEquals(e, E.R)
e = E.G
assertEquals(e, E.G)
assertEquals(K, nonStrict)
nonStrict = S
assertEquals(S, nonStrict)
assertEquals(arr[0], -51)
assertEquals(arr[1], -19)
arr[0] = 51
arr[1] = 19
assertEquals(arr[0], 51)
assertEquals(arr[1], 19)
assertEquals(true, b)
b = false
assertEquals(false, b)
// Check that subtyping via Nothing-returning functions does not break compiler.
assertFailsWith<NotImplementedError> {
ui = TODO()
t.i = TODO()
next = TODO()
e = TODO()
nonStrict = TODO()
b = TODO()
}
}
memScoped {
val packed = alloc<Packed>()
packed.i = -1
assertEquals(-1, packed.i)
packed.e = E.R
assertEquals(E.R, packed.e)
// Check that subtyping via Nothing-returning functions does not break compiler.
assertFailsWith<NotImplementedError> {
packed.i = TODO()
packed.e = TODO()
}
}
// Check that generics doesn't break anything.
checkEnumSubTyping(E.R)
checkIntSubTyping(630090)
memScoped {
val SIZE = 10
val flex = alloc(sizeOf<WithFlexibleArray>() + sizeOf<IntVar>() * SIZE, alignOf<WithFlexibleArray>()).reinterpret<WithFlexibleArray>()
flex.size = SIZE
for (i in 0 until SIZE) {
flex.data[i] = i
}
assertEquals(SIZE, flex.size)
for (i in 0 until SIZE) {
assertEquals(i, flex.data[i])
}
}
memScoped {
val SIZE = 10
val flex = alloc(sizeOf<WithZeroSizedArray>() + sizeOf<IntVar>() * SIZE, alignOf<WithZeroSizedArray>()).reinterpret<WithZeroSizedArray>()
assertEquals(4, sizeOf<WithZeroSizedArray>())
assertEquals(4, alignOf<WithZeroSizedArray>())
flex.size = SIZE
for (i in 0 until SIZE) {
flex.data[i] = i
}
assertEquals(SIZE, flex.size)
for (i in 0 until SIZE) {
assertEquals(i, flex.data[i])
}
}
memScoped {
val SIZE = 10
assertEquals(8, sizeOf<WithFlexibleArrayWithPadding>())
assertEquals(8, alignOf<WithFlexibleArrayWithPadding>())
val flex = alloc(sizeOf<WithFlexibleArrayWithPadding>() + sizeOf<LongVar>() * SIZE, alignOf<WithFlexibleArrayWithPadding>())
.reinterpret<WithFlexibleArrayWithPadding>()
fillArray(flex.ptr, SIZE)
assertEquals(SIZE, flex.size)
assertEquals('!'.code.toByte(), flex.c);
for (i in 0 until SIZE) {
assertEquals((i.toLong() shl 32) or (i.toLong() * 100), flex.data[i])
}
}
return "OK"
}
fun <T : E> checkEnumSubTyping(e: T) = memScoped {
val s = alloc<Complex>()
s.e = e
}
fun <T : Int> checkIntSubTyping(x: T) = memScoped {
val s = alloc<Trivial>()
s.i = x
}
@@ -0,0 +1,132 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: ctypes.def
---
// KT-28065
struct StructWithConstFields {
int x;
const int y;
};
struct StructWithConstFields getStructWithConstFields() {
struct StructWithConstFields result = { 111, 222 };
return result;
}
enum ForwardDeclaredEnum;
enum ForwardDeclaredEnum {
ZERO, ONE, TWO
};
static int vlaSum(int size, int array[size]) {
int result = 0;
for (int i = 0; i < size; ++i) {
result += array[i];
}
return result;
}
static int vlaSum2D(int size, int array[][size]) {
int result = 0;
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
result += array[i][j];
}
}
return result;
}
static int vlaSum2DBothDimensions(int rows, int columns, int array[rows][columns]) {
int result = 0;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < columns; ++j) {
result += array[i][j];
}
}
return result;
}
/*
// Not supported by clang:
static int vlaSum2DForward(int size; int array[][size], int size) {
return vlaSum2D(size, array);
}
*/
// "Strict" enums heuristic based on whether enum constants are defined explicitly:
enum StrictEnum1 {
StrictEnum1A,
StrictEnum1B
};
enum StrictEnum2 {
StrictEnum2A __attribute__((unused)),
StrictEnum2B __attribute__((unused))
};
enum NonStrictEnum1 {
NonStrictEnum1A = 0,
NonStrictEnum1B __attribute__((unused))
};
enum NonStrictEnum2 {
NonStrictEnum2A,
NonStrictEnum2B __attribute__((unused)) = 1
};
// KT-34025
typedef char Char;
enum EnumCharBase : Char {
EnumCharBaseA,
EnumCharBaseB
};
static int sendEnum(enum EnumCharBase x) {
return (int)x + 2;
}
enum EnumExplicitChar : char {
EnumExplicitCharA = 'a',
EnumExplicitCharB = 'b',
EnumExplicitCharDup = 'a'
};
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.native.*
import kotlin.test.*
import ctypes.*
fun box(): String {
getStructWithConstFields().useContents {
assertEquals(111, x)
assertEquals(222, y)
}
assertEquals(1u, ForwardDeclaredEnum.ONE.value)
assertEquals(6, vlaSum(3, cValuesOf(1, 2, 3)))
assertEquals(10, vlaSum2D(2, cValuesOf(1, 2, 3, 4)))
assertEquals(21, vlaSum2DBothDimensions(2, 3, cValuesOf(1, 2, 3, 4, 5, 6)))
// Not supported by clang:
// assertEquals(10, vlaSum2DForward(cValuesOf(1, 2, 3, 4), 2))
assertEquals(0u, StrictEnum1.StrictEnum1A.value)
assertEquals(1u, StrictEnum2.StrictEnum2B.value)
assertEquals(0u, NonStrictEnum1A)
assertEquals(1u, NonStrictEnum2B)
assertEquals(1, EnumCharBase.EnumCharBaseB.value)
assertEquals(3, sendEnum(EnumCharBase.EnumCharBaseB))
assertEquals('a'.toByte(), EnumExplicitCharA)
assertEquals('b'.toByte(), EnumExplicitCharB)
assertEquals(EnumExplicitCharA, EnumExplicitCharDup)
return "OK"
}
@@ -0,0 +1,63 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cunion.def
---
typedef union {
short s;
long long ll;
} BasicUnion;
typedef struct {
union {
int i;
float f;
} as;
} StructWithUnion;
typedef union {
unsigned int i : 31;
unsigned char b : 1;
} Packed;
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.experimental.ExperimentalNativeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import cunion.*
import kotlinx.cinterop.*
import kotlin.native.*
import kotlin.test.*
fun box(): String {
memScoped {
val basicUnion = alloc<BasicUnion>()
for (value in Short.MIN_VALUE..Short.MAX_VALUE) {
basicUnion.ll = value.toLong()
val expected = if (Platform.isLittleEndian) {
value
} else {
value.toLong() ushr (Long.SIZE_BITS - Short.SIZE_BITS)
}
assertEquals(expected.toShort(), basicUnion.s)
}
}
memScoped {
val struct = alloc<StructWithUnion>()
struct.`as`.i = Float.NaN.toRawBits()
assertEquals(Float.NaN, struct.`as`.f)
}
memScoped {
val union = alloc<Packed>()
union.b = 1u
var expected = if (Platform.isLittleEndian) {
1u
} else {
1u shl (Int.SIZE_BITS - Byte.SIZE_BITS)
}
assertEquals(expected, union.i)
union.i = 0u
assertEquals(0u, union.b)
}
return "OK"
}
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2018 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cunsupported.def
compilerOpts = -mno-xsave
---
static void noAttr() {}
__attribute__((always_inline)) noTargetAttr() {}
__attribute__((always_inline, __target__("xsave"))) void plainAttrs1() {}
__attribute__((__target__("xsave"), always_inline)) void plainAttrs2() {}
#define TARGET __target__
__attribute__((always_inline, TARGET("xsave"))) void macroAttr1() {}
__attribute__((TARGET("xsave"), always_inline)) void macroAttr2() {}
#define TARGET_ATTR __target__("xsave")
__attribute__((TARGET_ATTR, always_inline)) void macroAttr3() {}
__attribute__((always_inline, TARGET_ATTR)) void macroAttr4() {}
#define ALL_ATTRS1 __attribute__((always_inline, __target__("xsave")))
ALL_ATTRS1 void macroAttr5() {}
#define ALL_ATTRS2 __attribute__((always_inline, __target__("xsave")))
ALL_ATTRS2 void macroAttr6() {}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.test.*
import cunsupported.*
fun box(): String {
noAttr()
noTargetAttr()
return "OK"
}
@@ -0,0 +1,30 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cvalues.def
---
_Bool isNullString(const char* str) {
return str == (const char*)0;
}
typedef const short* LPCWSTR;
_Bool isNullWString(LPCWSTR str) {
return str == (LPCWSTR)0;
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import kotlin.test.*
import cvalues.*
fun box(): String {
assertTrue(isNullString(null))
assertTrue(isNullWString(null))
assertFalse(isNullString("a"))
assertFalse(isNullWString("b"))
return "OK"
}
@@ -0,0 +1,64 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cvectors.def
---
typedef float __attribute__ ((__vector_size__ (16))) KVector4f;
typedef int __attribute__ ((__vector_size__ (16))) KVector4i32;
struct Complex {
unsigned int ui;
KVector4f vec4f;
struct Complex* next;
int arr[2];
};
struct Complex produceComplexVector() {
struct Complex complex = {
.ui = 128,
.vec4f = {1.0, 1.0, 1.0, 1.0},
.next = 0,
.arr = {-51, -19}
};
return complex;
};
static float sendV4F(KVector4f v) {
return v[0] + 2 * v[1] + 4 * v[2] + 8 * v[3];
}
static int sendV4I(KVector4i32 v) {
return v[0] + 2 * v[1] + 4 * v[2] + 8 * v[3];
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalNativeApi::class)
import kotlinx.cinterop.*
import kotlinx.cinterop.vectorOf
import kotlin.native.*
import kotlin.test.*
import cvectors.*
fun box(): String {
produceComplexVector().useContents {
assertEquals(vec4f, vectorOf(1.0f, 1.0f, 1.0f, 1.0f))
vec4f = vectorOf(0.0f, 0.0f, 0.0f, 0.0f)
assertEquals(vec4f, vectorOf(0.0f, 0.0f, 0.0f, 0.0f))
}
// FIXME: KT-36285
if (Platform.osFamily != OsFamily.LINUX || Platform.cpuArchitecture != CpuArchitecture.ARM32) {
assertEquals(49, sendV4I(vectorOf(1, 2, 3, 4)))
}
assertEquals(49, (sendV4F(vectorOf(1f, 2f, 3f, 4f)) + 0.00001).toInt())
memScoped {
val vector = alloc<KVector4i32Var>().also {
it.value = vectorOf(1, 2, 3, 4)
}
assertEquals(vector.value, vectorOf(1, 2, 3, 4))
}
return "OK"
}
@@ -0,0 +1,138 @@
/*
* Copyright 2010-2023 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.
*/
// May need disabling when gcSchedulerType=aggressive . since it may be too slow
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: bitfields.def
---
enum B2 {
ZERO, ONE, TWO, THREE
};
enum E : short {
A, B
};
struct __attribute__((packed)) S {
long long x1 : 1;
enum B2 x2 : 2;
unsigned short x3 : 3;
unsigned int x4 : 4;
int x5 : 5;
long long x6 : 63;
enum E x7: 2;
_Bool x8 : 1;
struct { int x9:4; };
};
static long long getX1(struct S* s) { return s->x1; }
static enum B2 getX2(struct S* s) { return s->x2; }
static unsigned short getX3(struct S* s) { return s->x3; }
static unsigned int getX4(struct S* s) { return s->x4; }
static int getX5(struct S* s) { return s->x5; }
static long long getX6(struct S* s) { return s->x6; }
static enum E getX7(struct S* s) { return s->x7; }
static _Bool getX8(struct S* s) { return s->x8; }
static int getX9(struct S* s) { return s->x9; }
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import bitfields.*
import kotlinx.cinterop.*
fun assertEquals(value1: Any?, value2: Any?) {
if (value1 != value2)
throw AssertionError("Expected $value1, got $value2")
}
fun check(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean, x9: Int) {
assertEquals(x1, s.x1)
assertEquals(x1, getX1(s.ptr))
assertEquals(x2, s.x2)
assertEquals(x2, getX2(s.ptr))
assertEquals(x3, s.x3)
assertEquals(x3, getX3(s.ptr))
assertEquals(x4, s.x4)
assertEquals(x4, getX4(s.ptr))
assertEquals(x5, s.x5)
assertEquals(x5, getX5(s.ptr))
assertEquals(x6, s.x6)
assertEquals(x6, getX6(s.ptr))
assertEquals(x7, s.x7)
assertEquals(x7, getX7(s.ptr))
assertEquals(x8, s.x8)
assertEquals(x8, getX8(s.ptr))
assertEquals(x9, s.x9)
assertEquals(x9, getX9(s.ptr))
}
fun assign(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean, x9: Int) {
s.x1 = x1
s.x2 = x2
s.x3 = x3
s.x4 = x4
s.x5 = x5
s.x6 = x6
s.x7 = x7
s.x8 = x8
s.x9 = x9
}
fun assignReversed(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean, x9: Int) {
s.x9 = x9
s.x8 = x8
s.x7 = x7
s.x6 = x6
s.x5 = x5
s.x4 = x4
s.x3 = x3
s.x2 = x2
s.x1 = x1
}
fun test(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean, x9: Int) {
assign(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
check(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
assignReversed(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
check(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
// Also check with some insignificant bits modified:
assign(s, x1 + 2, x2, (x3 + 8u).toUShort(), x4 - 16u, x5 + 32, x6 + Long.MIN_VALUE, x7, x8, x9 + 16)
check(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
assignReversed(s, x1 + 2, x2, (x3 + 8u).toUShort(), x4 - 16u, x5 + 32, x6 + Long.MIN_VALUE, x7, x8, x9 + 16)
check(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
}
fun box(): String {
memScoped {
val s = alloc<S>()
for (x1 in -1L..0L)
for (x2 in arrayOf(B2.ZERO, B2.ONE, B2.THREE))
for (x3 in ushortArrayOf(0u, 2u, 7u))
for (x4 in uintArrayOf(0u, 6u, 15u))
for (x5 in intArrayOf(-16, -1, 0, 5, 15))
for (x6 in longArrayOf(Long.MIN_VALUE/2, -325L, 0, 1L shl 48, Long.MAX_VALUE/2))
for (x7 in E.values())
for (x8 in arrayOf(false, true))
for (x9 in intArrayOf(-8, -1, 0, 5, 7)) // 4 bits width
test(s, x1, x2, x3.toUShort(), x4, x5, x6, x7, x8, x9)
}
return "OK"
}
@@ -0,0 +1,155 @@
/*
* Copyright 2010-2023 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: ccallbacksAndVarargs.def
---
#include <stdarg.h>
struct S {
int x;
};
static int getX(struct S (*callback)(void)) {
return callback().x;
}
static void applyCallback(struct S s, void (*callback)(struct S)) {
callback(s);
}
static struct S makeS(int x, ...) {
return (struct S){ x };
}
enum E {
ZERO, ONE, TWO
};
static enum E makeE(int ordinal, ...) {
return ordinal;
}
struct Args {
char a1;
char a2;
short a3;
int a4;
long long a5;
float a6;
double a7;
void* a8;
unsigned char a9;
unsigned short a10;
unsigned int a11;
unsigned long long a12;
enum E a13;
struct S a14;
void* a15;
};
static struct Args getVarargs(int ignore, ...) {
va_list args;
va_start(args, ignore);
struct Args result = {
va_arg(args, char),
va_arg(args, char),
va_arg(args, short),
va_arg(args, int),
va_arg(args, long long),
va_arg(args, double),
va_arg(args, double),
va_arg(args, void*),
va_arg(args, unsigned char),
va_arg(args, unsigned short),
va_arg(args, unsigned int),
va_arg(args, unsigned long long),
va_arg(args, enum E),
va_arg(args, struct S),
va_arg(args, void*)
};
va_end(args);
return result;
}
static int sum(int first, int second) {
return first + second;
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.test.*
import kotlinx.cinterop.*
import ccallbacksAndVarargs.*
fun box(): String {
testStructCallbacks()
testVarargs()
testCallableReferences()
return "OK"
}
fun testStructCallbacks() {
assertEquals(42, getX(staticCFunction { -> cValue<S> { x = 42 } }))
applyCallback(cValue { x = 17 }, staticCFunction { it: CValue<S> ->
assertEquals(17, it.useContents { x })
})
assertEquals(66, makeS(66, 111).useContents { x })
}
fun testVarargs() {
assertEquals(E.ONE, makeE(1))
getVarargs(
0,
true,
2.toByte(),
Short.MIN_VALUE,
42,
Long.MAX_VALUE,
3.14f,
2.71,
0x1234ABCDL.toCPointer<COpaque>(),
UByte.MAX_VALUE,
22.toUShort(),
111u,
ULong.MAX_VALUE,
E.TWO,
cValue<S> { x = 15 },
null
).useContents {
assertEquals(1, a1)
assertEquals(2.toByte(), a2)
assertEquals(Short.MIN_VALUE, a3)
assertEquals(42, a4)
assertEquals(Long.MAX_VALUE, a5)
assertEquals(3.14f, a6)
assertEquals(2.71, a7)
assertEquals(0x1234ABCDL, a8.toLong())
assertEquals(UByte.MAX_VALUE, a9)
assertEquals(22.toUShort(), a10)
assertEquals(111u, a11)
assertEquals(ULong.MAX_VALUE, a12)
assertEquals(E.TWO, a13)
assertEquals(15, a14.x)
assertEquals(null, a15)
}
}
fun testCallableReferences() {
val sumRef = ::sum
assertEquals(3, sumRef(1, 2))
val sumPtr = staticCFunction(::sum)
assertEquals(7, sumPtr(3, 4))
}
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cenums.def
---
enum E {
A, B, C
};
// MODULE: main(cinterop)
// FILE: main.kt
// !LANGUAGE: +EnumEntries
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import cenums.*
import kotlinx.cinterop.*
import kotlin.test.*
@OptIn(kotlin.ExperimentalStdlibApi::class)
fun box(): String {
memScoped {
val e = alloc<E.Var>()
e.value = E.C
assertEquals(E.C, e.value)
assertFailsWith<NotImplementedError> {
e.value = TODO()
}
}
val values = E.values()
assertEquals(values[0], E.A)
assertEquals(values[1], E.B)
assertEquals(values[2], E.C)
// TODO: temporariry commented. Task for investigation is KT-56107
// val entries = E.entries
// assertEquals(entries[0], E.A)
// assertEquals(entries[1], E.B)
// assertEquals(entries[2], E.C)
return "OK"
}
@@ -0,0 +1,37 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cCallback.def
language = C
---
extern char* sb;
void runAndCatch(void(*f)(void));
// FILE: cCallback.cpp
#include <stdio.h>
char* sb = nullptr;
extern "C" void runAndCatch(void(*f)(void)) {
try {
f();
} catch (...) {
sb = "OK";
}
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.staticCFunction
import kotlinx.cinterop.toKString
import cCallback.runAndCatch
import cCallback.sb
fun throwingCallback() {
throw IllegalStateException("Kotlin Exception!")
}
fun box(): String {
runAndCatch(staticCFunction(::throwingCallback))
return sb?.toKString() ?: "FAIL"
}
@@ -0,0 +1,56 @@
// This test mostly checks frontend behaviour.
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cForwardDeclarations.def
---
struct StructDeclared;
struct StructDefined { int x; };
int useStructDeclared(struct StructDeclared* declared) {
return -1;
}
int useStructDefined(struct StructDefined* defined) {
return -2;
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import cForwardDeclarations.*
import cnames.structs.StructDeclared
import kotlin.test.assertEquals
import kotlinx.cinterop.COpaque
import kotlinx.cinterop.CStructVar
import kotlinx.cinterop.ptr
// The test should also check that these references can't be resolved, but the test infra doesn't support this yet:
// import cForwardDeclarations.StructUndeclared
// import cnames.structs.StructUndeclared // Supported in K1 though.
fun <T1 : T2, T2> checkSubtype2() {}
// Here we rely on frontend reporting conflicting overloads if some of these types turn out to be the same.
fun checkDifferentTypes(s: StructDeclared?) = 1
fun checkDifferentTypes(s: StructDefined?) = 2
fun box(): String {
checkSubtype2<StructDeclared, COpaque>()
checkSubtype2<StructDefined, CStructVar>()
val declared: StructDeclared? = null
val defined: StructDefined? = null
assertEquals(1, checkDifferentTypes(declared))
assertEquals(2, checkDifferentTypes(defined))
assertEquals(-1, useStructDeclared(declared?.ptr))
assertEquals(-2, useStructDefined(defined?.ptr))
return "OK"
}
@@ -0,0 +1,130 @@
// This test mostly checks frontend behaviour.
// TARGET_BACKEND: NATIVE
// MODULE: cinterop1
// FILE: cForwardDeclarationsTwoLibs1.def
---
struct StructDeclaredUndeclared;
struct StructDeclaredDeclared;
struct StructDeclaredDefined;
struct StructDefinedUndeclared {};
struct StructDefinedDeclared {};
struct StructDefinedDefined {};
int use1StructDeclaredUndeclared(struct StructDeclaredUndeclared* declaredUndeclared) { return -3; }
int use1StructDeclaredDeclared(struct StructDeclaredDeclared* declaredDeclared) { return -4; }
int use1StructDeclaredDefined(struct StructDeclaredDefined* declaredDefined) { return -5; }
int use1StructDefinedUndeclared(struct StructDefinedUndeclared* definedUndeclared) { return -6; }
int use1StructDefinedDeclared(struct StructDefinedDeclared* definedDeclared) { return -7; }
int use1StructDefinedDefined(struct StructDefinedDefined* definedDefined) { return -8; }
// MODULE: cinterop2
// FILE: cForwardDeclarationsTwoLibs2.def
---
struct StructUndeclaredDeclared;
struct StructUndeclaredDefined {};
struct StructDeclaredDeclared;
struct StructDeclaredDefined {};
struct StructDefinedDeclared;
struct StructDefinedDefined {};
int use2StructUndeclaredDeclared(struct StructUndeclaredDeclared* undeclaredDeclared) { return 1; }
int use2StructUndeclaredDefined(struct StructUndeclaredDefined* undeclaredDefined) { return 2; }
int use2StructDeclaredDeclared(struct StructDeclaredDeclared* declaredDeclared) { return 4; }
int use2StructDeclaredDefined(struct StructDeclaredDefined* declaredDefined) { return 5; }
int use2StructDefinedDeclared(struct StructDefinedDeclared* definedDeclared) { return 7; }
int use2StructDefinedDefined(struct StructDefinedDefined* definedDefined) { return 8; }
// MODULE: main(cinterop1, cinterop2)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import cForwardDeclarationsTwoLibs1.*
import cForwardDeclarationsTwoLibs2.*
import cnames.structs.StructUndeclaredDeclared
import cnames.structs.StructDeclaredUndeclared
import cnames.structs.StructDeclaredDeclared
import kotlin.test.assertEquals
import kotlinx.cinterop.COpaque
import kotlinx.cinterop.CPointed
import kotlinx.cinterop.CStructVar
import kotlinx.cinterop.ptr
// The test should also check that these references can't be resolved, but the test infra doesn't support this yet:
// import cForwardDeclarationsTwoLibs1.StructUndeclaredUndeclared
// import cForwardDeclarationsTwoLibs1.StructUndeclaredDeclared
// import cForwardDeclarationsTwoLibs1.StructUndeclaredDefined
// import cForwardDeclarationsTwoLibs2.StructUndeclaredUndeclared
// import cForwardDeclarationsTwoLibs2.StructDeclaredUndeclared
// import cForwardDeclarationsTwoLibs2.StructDefinedUndeclared
// import cnames.structs.StructUndeclaredUndeclared // Supported in K1 though.
fun <T1 : T2, T2> checkSubtype2() {}
// Here we rely on frontend reporting conflicting overloads if some of these types turn out to be the same.
fun checkDifferentTypes(s: StructUndeclaredDeclared?) = 1
fun checkDifferentTypes(s: StructUndeclaredDefined?) = 2
fun checkDifferentTypes(s: StructDeclaredUndeclared?) = 3
fun checkDifferentTypes(s: StructDeclaredDeclared?) = 4
fun checkDifferentTypes(s: StructDeclaredDefined?) = 5
fun checkDifferentTypes(s: StructDefinedUndeclared?) = 6
fun checkDifferentTypes(s: StructDefinedDeclared?) = 7
fun checkDifferentTypes(s: cForwardDeclarationsTwoLibs1.StructDefinedDefined?) = 8
fun checkDifferentTypes(s: cForwardDeclarationsTwoLibs2.StructDefinedDefined?) = 9
fun box(): String {
checkSubtype2<StructUndeclaredDeclared, COpaque>()
checkSubtype2<StructUndeclaredDefined, CStructVar>()
checkSubtype2<StructDeclaredUndeclared, COpaque>()
checkSubtype2<StructDeclaredDeclared, COpaque>()
checkSubtype2<cnames.structs.StructDeclaredDefined, CPointed>()
checkSubtype2<StructDeclaredDefined, CStructVar>()
checkSubtype2<StructDefinedUndeclared, CStructVar>()
checkSubtype2<cnames.structs.StructDefinedDeclared, CPointed>()
checkSubtype2<StructDefinedDeclared, CStructVar>()
checkSubtype2<cForwardDeclarationsTwoLibs1.StructDefinedDefined, CStructVar>()
checkSubtype2<cForwardDeclarationsTwoLibs2.StructDefinedDefined, CStructVar>()
val undeclaredDeclared: StructUndeclaredDeclared? = null
val undeclaredDefined: StructUndeclaredDefined? = null
val declaredUndeclared: StructDeclaredUndeclared? = null
val declaredDeclared: StructDeclaredDeclared? = null
val cnamesDeclaredDefined: cnames.structs.StructDeclaredDefined? = null
val declaredDefined: StructDeclaredDefined? = null
val definedUndeclared: StructDefinedUndeclared? = null
val cnamesDefinedDeclared: cnames.structs.StructDefinedDeclared? = null
val definedDeclared: StructDefinedDeclared? = null
val definedDefined1: cForwardDeclarationsTwoLibs1.StructDefinedDefined? = null
val definedDefined2: cForwardDeclarationsTwoLibs2.StructDefinedDefined? = null
assertEquals(1, checkDifferentTypes(undeclaredDeclared))
assertEquals(2, checkDifferentTypes(undeclaredDefined))
assertEquals(3, checkDifferentTypes(declaredUndeclared))
assertEquals(4, checkDifferentTypes(declaredDeclared))
assertEquals(5, checkDifferentTypes(declaredDefined))
assertEquals(6, checkDifferentTypes(definedUndeclared))
assertEquals(7, checkDifferentTypes(definedDeclared))
assertEquals(8, checkDifferentTypes(definedDefined1))
assertEquals(9, checkDifferentTypes(definedDefined2))
assertEquals(1, use2StructUndeclaredDeclared(undeclaredDeclared?.ptr))
assertEquals(2, use2StructUndeclaredDefined(undeclaredDefined?.ptr))
assertEquals(-3, use1StructDeclaredUndeclared(declaredUndeclared?.ptr))
assertEquals(-4, use1StructDeclaredDeclared(declaredDeclared?.ptr))
assertEquals(4, use2StructDeclaredDeclared(declaredDeclared?.ptr))
assertEquals(-5, use1StructDeclaredDefined(cnamesDeclaredDefined?.ptr))
assertEquals(5, use2StructDeclaredDefined(declaredDefined?.ptr))
assertEquals(-6, use1StructDefinedUndeclared(definedUndeclared?.ptr))
assertEquals(-7, use1StructDefinedDeclared(definedDeclared?.ptr))
assertEquals(7, use2StructDefinedDeclared(cnamesDefinedDeclared?.ptr))
assertEquals(-8, use1StructDefinedDefined(definedDefined1?.ptr))
assertEquals(8, use2StructDefinedDefined(definedDefined2?.ptr))
return "OK"
}
@@ -0,0 +1,77 @@
/*
* Copyright 2010-2023 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: cglobals.def
---
const int g1 = 42;
int g2 = 17;
struct S {
int x;
} g3 = { 128 };
int g4[2] = { 13, 14 };
int g5[2][2] = { 15, 16, 17, 18 };
struct S* const g6 = &g3;
void globals_foo() {
// Test that local vars are not treated as global ones.
float g1;
}
// Test non-compilable variable:
typedef int MyInt;
MyInt g7;
#define g7 bad macro
// Test property name mangling:
struct g1 {};
struct g1_ {};
typedef void* voidptr;
_Pragma("clang assume_nonnull begin")
const voidptr g8 = 0x1, g9 = 0x2;
_Pragma("clang assume_nonnull end")
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalNativeApi::class)
import kotlinx.cinterop.*
import cglobals.*
fun box(): String {
assert(g1__ == 42)
assert(g2 == 17)
g2 = 42
assert(g2 == 42)
assert(g3.x == 128)
g3.x = 7
assert(g3.x == 7)
assert(g4[1] == 14)
g4[1] = 15
assert(g4[1] == 15)
assert(g5[0] == 15)
assert(g5[3] == 18)
g5[0] = 16
assert(g5[0] == 16)
assert(g6 == g3.ptr)
assert(g8.toLong() == 0x1L)
assert(g9.toLong() == 0x2L)
return "OK"
}
@@ -0,0 +1,124 @@
// FREE_CINTEROP_ARGS: -header incompleteTypes.h
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: incompleteTypes.def
# The def file is intentionally empty
# `incompleteTypes.h` is meant to be included via `-header` option of cinterop tool
// FILE: incompleteTypes.h
#ifdef __cplusplus
extern "C" {
#endif
// Forward declaration.
struct S;
extern struct S s;
const char* getContent(struct S* s);
void setContent(struct S* s, const char* name);
union U;
extern union U u;
double getDouble(union U* u);
void setDouble(union U* u, double value);
// Global array of unknown size.
extern char array[];
int arrayLength();
void setArrayValue(char* array, char value);
#ifdef __cplusplus
}
#endif
// FILE: incompleteTypes.cpp
#include <string>
#include "incompleteTypes.h"
extern "C" {
struct S {
std::string name;
};
S s = {
.name = "initial"
};
void setContent(struct S* s, const char* name) {
// Note that copy here is intentional: we use it as a workaround
// for short lifetime of copy of the passed Kotlin string.
s->name = name;
}
const char* getContent(struct S* s) {
return s->name.c_str();
}
union U {
float f;
double d;
};
void setDouble(union U* u, double value) {
u->d = value;
}
double getDouble(union U* u) {
return u->d;
}
union U u = {
.d = 0.0
};
char array[5] = { 0, 0, 0, 0, 0 };
void setArrayValue(char* array, char value) {
for (int i = 0; i < 5; ++i) {
array[i] = value;
}
}
int arrayLength() {
return sizeof(array) / sizeof(char);
}
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import incompleteTypes.*
import kotlinx.cinterop.*
import kotlin.test.*
fun box(): String {
assertNotNull(s.ptr)
assertNotNull(u.ptr)
assertNotNull(array)
assertEquals("initial", getContent(s.ptr)?.toKString())
setContent(s.ptr, "yo")
val ptr = getContent(s.ptr)
assertEquals("yo", ptr?.toKString())
assertEquals(0.0, getDouble(u.ptr))
setDouble(u.ptr, Double.MIN_VALUE)
assertEquals(Double.MIN_VALUE, getDouble(u.ptr))
for (i in 0 until arrayLength()) {
assertEquals(0x0, array[i])
}
setArrayValue(array, 0x1)
for (i in 0 until arrayLength()) {
assertEquals(0x1, array[i])
}
return "OK"
}
@@ -0,0 +1,23 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: kt43265.def
strictEnums = bcm2835FunctionSelect
---
enum bcm2835FunctionSelect {
BCM2835_GPIO_FSEL_INPT = 0x00, BCM2835_GPIO_FSEL_OUTP = 0x01, BCM2835_GPIO_FSEL_ALT0 = 0x04, BCM2835_GPIO_FSEL_ALT1 = 0x05,
BCM2835_GPIO_FSEL_ALT2 = 0x06, BCM2835_GPIO_FSEL_ALT3 = 0x07, BCM2835_GPIO_FSEL_ALT4 = 0x03, BCM2835_GPIO_FSEL_ALT5 = 0x02,
BCM2835_GPIO_FSEL_MASK = 0x07
};
// MODULE: main(cinterop)
// FILE: main.kt
import kt43265.*
import kotlin.test.*
@kotlinx.cinterop.ExperimentalForeignApi
fun box(): String {
assertEquals(bcm2835FunctionSelect.BCM2835_GPIO_FSEL_ALT3, bcm2835FunctionSelect.BCM2835_GPIO_FSEL_MASK)
return "OK"
}
@@ -0,0 +1,58 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: kt44283.def
---
#include <stdlib.h>
#include <pthread.h>
typedef struct {
int d;
} TestStruct;
typedef struct {
void (*f)(TestStruct data);
} ThreadData;
void *dispatch(void *rawArg) {
ThreadData *arg = rawArg;
arg->f((TestStruct) {.d = 1});
return NULL;
}
void invokeFromThread(void (*f)(TestStruct data)) {
pthread_t thread_id;
ThreadData *threadData = malloc(sizeof(ThreadData));
threadData->f = f;
pthread_create(&thread_id, NULL, dispatch, (void *) threadData);
pthread_join(thread_id, NULL);
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class)
import kotlinx.cinterop.*
import kt44283.*
import kotlin.concurrent.AtomicInt
import kotlin.test.*
val callbackCounter = AtomicInt(0)
@ExperimentalForeignApi
fun box(): String {
val func = staticCFunction<CValue<TestStruct>, Unit> {
kotlin.native.runtime.GC.collect() // Helps to ensure that "runtime" is already initialized.
memScoped {
println("Hello, Kotlin/Native! ${it.ptr.pointed.d}")
}
callbackCounter.incrementAndGet()
}
assertEquals(0, callbackCounter.value)
invokeFromThread(func.reinterpret())
assertEquals(1, callbackCounter.value)
return "OK"
}
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: kt51925.def
strictEnums = E
---
enum E {
X = 1, Y = 2, Z = 42
};
typedef struct {
int d;
} Struct;
// MODULE: lib(cinterop)
// FILE: lib.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kt51925.*
import kotlinx.cinterop.*
fun bar1(e: E) = e.value
inline fun foo1() = bar1(E.Z)
fun bar2(s: Struct): Int {
return s.d
}
inline fun foo2(): Int {
memScoped {
val s = alloc<Struct>()
s.d = 42
return bar2(s)
}
}
// MODULE: main(lib)
// FILE: main.kt
import kotlin.test.*
fun box(): String {
assertEquals(42u, foo1())
assertEquals(42, foo2())
return "OK"
}
@@ -0,0 +1,30 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: kt54284.def
---
#define KFILE "FILE:" __FILE__
#define KLINE "LINE:" __LINE__
#define KTIME "TIME:" __TIME__
#define KDATE "DATE:" __DATE__
#define KFILENAME "NAME:" __FILE_NAME__
#define KBASEFILE "BASE:" __BASE_FILE__
// MODULE: main(cinterop)
// FILE: main.kt
import kotlinx.cinterop.*
import kt54284.*
import kotlin.test.*
@ExperimentalForeignApi
fun box(): String {
assertEquals("FILE:__FILE__", KFILE)
assertEquals("LINE:__LINE__", KLINE)
assertEquals("TIME:__TIME__", KTIME)
assertEquals("DATE:__DATE__", KDATE)
assertEquals("NAME:__FILE_NAME__", KFILENAME)
assertEquals("BASE:__BASE_FILE__", KBASEFILE)
return "OK"
}
@@ -0,0 +1,30 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: kt54284_fmodules.def
compilerOpts = -fmodules
---
#define KFILE "FILE:" __FILE__
#define KLINE "LINE:" __LINE__
#define KTIME "TIME:" __TIME__
#define KDATE "DATE:" __DATE__
#define KFILENAME "NAME:" __FILE_NAME__
#define KBASEFILE "BASE:" __BASE_FILE__
// MODULE: main(cinterop)
// FILE: main.kt
import kotlinx.cinterop.*
import kt54284_fmodules.*
import kotlin.test.*
@ExperimentalForeignApi
fun box(): String {
assertEquals("FILE:__FILE__", KFILE)
assertEquals("LINE:__LINE__", KLINE)
assertEquals("TIME:__TIME__", KTIME)
assertEquals("DATE:__DATE__", KDATE)
assertEquals("NAME:__FILE_NAME__", KFILENAME)
assertEquals("BASE:__BASE_FILE__", KBASEFILE)
return "OK"
}
+680
View File
@@ -0,0 +1,680 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: kt57640.def
language = Objective-C
headers = kt57640.h
// FILE: kt57640.h
#import <Foundation/NSObject.h>
@interface Base : NSObject
@property (readwrite) Base* delegate;
@end
@protocol Foo
@property (readwrite) id<Foo> delegate;
@end
@protocol Bar
@property (readwrite) id<Bar> delegate;
@end
@interface Derived : Base<Bar, Foo>
// This interface does not have re-declaration of property `delegate`.
// Return type of getter `delegate()` and param type of setter `setDelegate()` are:
// the type of property defined in the first mentioned protocol (id<Bar>), which is incompatible with property type.
@end
@interface DerivedWithPropertyOverride : Base<Bar, Foo>
// This interface does not have re-declaration of property `delegate`.
// Return type of getter `delegate()` and param type of setter `setDelegate()` are `DerivedWithPropertyOverride*`
@property (readwrite) DerivedWithPropertyOverride* delegate;
@end
// FILE: kt57640.m
#import "kt57640.h"
@implementation Base
@end
@implementation Derived
@end
@implementation DerivedWithPropertyOverride
@end
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kt57640.*
import kotlin.test.*
class GrandDerived: Derived() {}
class GrandDerivedWithPropertyOverride: DerivedWithPropertyOverride() {}
/**
* class KotlinInterfaceDerived would cause errors, this deserves a diagnostic test
* error: class 'KotlinInterfaceDerived' must override 'delegate' because it inherits multiple implementations for it.
* error: 'delegate' clashes with 'delegate': return types are incompatible.
* error: 'delegate' clashes with 'delegate': property types do not match.
*/
//class KotlinInterfaceDerived: Base(), FooProtocol, BarProtocol
fun box(): String {
testBase()
testAssignmentDerivedToDerived()
testAssignmentDerivedToBase()
testAssignmentBaseToDerived()
testAssignmentDerivedWithPropertyOverrideToDerivedWithPropertyOverride()
testAssignmentDerivedWithPropertyOverrideToBase()
testAssignmentBaseToDerivedWithPropertyOverride()
testGrandDerived()
testGrandDerivedWithPropertyOverride()
testAssigmmentDerivedWithPropertyOverrideToGrandDerivedWithPropertyOverride()
return "OK"
}
private fun testBase() {
val base = Base()
val delegate00_Base: Base? = base.delegate
assertEquals(null, delegate00_Base)
val delegate01_Base: Base? = base.delegate()
assertEquals(null, delegate01_Base)
base.delegate = base
val delegate02_Base: Base? = base.delegate
assertEquals(base, delegate02_Base)
val delegate03_Base: Base? = base.delegate()
assertEquals(base, delegate03_Base)
}
private fun testAssignmentDerivedToDerived() {
val derived = Derived()
val delegate10_Base: Base? = derived.delegate
assertEquals(null, delegate10_Base)
val delegate11_Bar: BarProtocol? = derived.delegate()
assertEquals(null, delegate11_Bar)
derived.delegate = derived
derived.setDelegate(derived)
val delegate12_Base: Base? = derived.delegate
assertTrue(delegate12_Base is Base)
assertTrue(delegate12_Base is FooProtocol)
assertTrue(delegate12_Base is BarProtocol)
assertTrue(delegate12_Base is Derived)
assertEquals(derived, delegate12_Base)
val delegate16_Bar: BarProtocol? = derived.delegate()
assertTrue(delegate16_Bar is Base)
assertTrue(delegate16_Bar is FooProtocol)
assertTrue(delegate16_Bar is BarProtocol)
assertTrue(delegate16_Bar is Derived)
assertEquals(derived, delegate16_Bar)
val delegate13_Base: Base? = (derived as Base).delegate
assertTrue(delegate13_Base is Base)
assertTrue(delegate13_Base is FooProtocol)
assertTrue(delegate13_Base is BarProtocol)
assertTrue(delegate13_Base is Derived)
assertEquals(derived, delegate13_Base)
val delegate17_Base: Base? = (derived as Base).delegate()
assertTrue(delegate17_Base is Base)
assertTrue(delegate17_Base is FooProtocol)
assertTrue(delegate17_Base is BarProtocol)
assertTrue(delegate17_Base is Derived)
assertEquals(derived, delegate17_Base)
val delegate14_Foo: FooProtocol? = (derived as FooProtocol).delegate
assertTrue(delegate14_Foo is Base)
assertTrue(delegate14_Foo is FooProtocol)
assertTrue(delegate14_Foo is BarProtocol)
assertTrue(delegate14_Foo is Derived)
assertEquals(derived, delegate14_Foo)
val delegate18_Foo: FooProtocol? = (derived as FooProtocol).delegate()
assertTrue(delegate18_Foo is Base)
assertTrue(delegate18_Foo is FooProtocol)
assertTrue(delegate18_Foo is BarProtocol)
assertTrue(delegate18_Foo is Derived)
assertEquals(derived, delegate18_Foo)
val delegate15_Bar: BarProtocol? = (derived as BarProtocol).delegate
assertTrue(delegate15_Bar is Base)
assertTrue(delegate15_Bar is FooProtocol)
assertTrue(delegate15_Bar is BarProtocol)
assertTrue(delegate15_Bar is Derived)
assertEquals(derived, delegate15_Bar)
val delegate19_Bar: BarProtocol? = (derived as BarProtocol).delegate()
assertTrue(delegate19_Bar is Base)
assertTrue(delegate19_Bar is FooProtocol)
assertTrue(delegate19_Bar is BarProtocol)
assertTrue(delegate19_Bar is Derived)
assertEquals(derived, delegate19_Bar)
}
private fun testAssignmentDerivedToBase() {
val base = Base()
val delegate10_Base: Base? = base.delegate
assertEquals(null, delegate10_Base)
val delegate11_Base: Base? = base.delegate()
assertEquals(null, delegate11_Base)
base.delegate = base
base.setDelegate(base)
val derived = Derived()
base.delegate = derived
val delegate12_Base: Base? = base.delegate
assertTrue(delegate12_Base is Base)
assertTrue(delegate12_Base is FooProtocol)
assertTrue(delegate12_Base is BarProtocol)
assertTrue(delegate12_Base is Derived)
assertEquals(derived, delegate12_Base)
val delegate16_Base: Base? = base.delegate()
assertTrue(delegate16_Base is Base)
assertTrue(delegate16_Base is FooProtocol)
assertTrue(delegate16_Base is BarProtocol)
assertTrue(delegate16_Base is Derived)
assertEquals(derived, delegate16_Base)
}
private fun testAssignmentBaseToDerived() {
val derived = Derived()
val delegate10_Base: Base? = derived.delegate
assertEquals(null, delegate10_Base)
val delegate11_Bar: BarProtocol? = derived.delegate()
assertEquals(null, delegate11_Bar)
val base = Base()
derived.delegate = base
// derived.setDelegate(base) // argument type mismatch, this deserves a diagnostic test
val delegate12_Base: Base? = derived.delegate
assertTrue(delegate12_Base is Base)
assertFalse(delegate12_Base is FooProtocol)
assertFalse(delegate12_Base is BarProtocol)
assertFalse(delegate12_Base is Derived)
assertEquals(base, delegate12_Base)
val delegate16_Bar: BarProtocol? = derived.delegate()
val delegate16_Any: Any? = delegate16_Bar
assertTrue(delegate16_Bar is Base)
assertTrue(delegate16_Any is Base)
assertFalse(delegate16_Bar is FooProtocol)
assertFalse(delegate16_Any is FooProtocol)
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
// while at run-time, the type is Base, which isn't BarProtocol, and the "is" result is "false"
// assertFalse(delegate16_Bar is BarProtocol)
assertFalse(delegate16_Any is BarProtocol) // actual type is Base, which isn't BarProtocol
assertFalse(delegate16_Bar is Derived)
assertFalse(delegate16_Any is Derived)
assertEquals(base, delegate16_Bar)
assertEquals(base, delegate16_Any)
val delegate13_Base: Base? = (derived as Base).delegate
assertTrue(delegate13_Base is Base)
assertFalse(delegate13_Base is FooProtocol)
assertFalse(delegate13_Base is BarProtocol)
assertFalse(delegate13_Base is Derived)
assertEquals(base, delegate13_Base)
val delegate17_Base: Base? = (derived as Base).delegate()
assertTrue(delegate17_Base is Base)
assertFalse(delegate17_Base is FooProtocol)
assertFalse(delegate17_Base is BarProtocol)
assertFalse(delegate17_Base is Derived)
assertEquals(base, delegate17_Base)
val delegate14_Foo: FooProtocol? = (derived as FooProtocol).delegate
val delegate14_Any: Any? = delegate14_Foo
assertTrue(delegate14_Foo is Base)
assertTrue(delegate14_Any is Base)
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
// while at run-time, the type is Base, which isn't FooProtocol, and the "is" result is "false"
// assertFalse(delegate14_Foo is FooProtocol)
assertFalse(delegate14_Any is FooProtocol) // actual type is Base, which isn't FooProtocol
assertFalse(delegate14_Foo is BarProtocol)
assertFalse(delegate14_Any is BarProtocol)
assertFalse(delegate14_Foo is Derived)
assertEquals(base, delegate14_Foo as Base)
assertEquals(base, delegate14_Any as Base)
val delegate18_Foo: FooProtocol? = (derived as FooProtocol).delegate()
val delegate18_Any: Any? = delegate18_Foo
assertTrue(delegate18_Foo is Base)
assertTrue(delegate18_Any is Base)
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
// while at run-time, the type is Base, which isn't FooProtocol, and the "is" result is "false"
// assertFalse(delegate18_Foo is FooProtocol)
assertFalse(delegate18_Any is FooProtocol) // actual type is Base, which isn't FooProtocol
assertFalse(delegate18_Foo is BarProtocol)
assertFalse(delegate18_Any is BarProtocol)
assertFalse(delegate18_Foo is Derived)
assertFalse(delegate18_Any is Derived)
assertEquals(base, delegate18_Foo)
assertEquals(base, delegate18_Any)
val delegate15_Bar: BarProtocol? = (derived as BarProtocol).delegate
val delegate15_Any: Any? = delegate15_Bar
assertTrue(delegate15_Bar is Base)
assertTrue(delegate15_Any is Base)
assertFalse(delegate15_Bar is FooProtocol)
assertFalse(delegate15_Any is FooProtocol)
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
// while at run-time, the type is Base, which isn't BarProtocol, and the "is" result is "false"
// assertFalse(delegate15_Bar is BarProtocol)
assertFalse(delegate15_Any is BarProtocol) // actual type is Base, which isn't BarProtocol
assertFalse(delegate15_Bar is Derived)
assertFalse(delegate15_Any is Derived)
assertEquals(base, delegate15_Bar as Base)
assertEquals(base, delegate15_Any as Base)
val delegate19_Bar: BarProtocol? = (derived as BarProtocol).delegate()
val delegate19_Any: Any? = delegate19_Bar
assertTrue(delegate19_Bar is Base)
assertTrue(delegate19_Any is Base)
assertFalse(delegate19_Bar is FooProtocol)
assertFalse(delegate19_Any is FooProtocol)
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
// while at run-time, the type is Base, which isn't BarProtocol, and the "is" result is "false"
// assertFalse(delegate19_Bar is BarProtocol)
assertFalse(delegate19_Any is BarProtocol) // actual type is Base, which isn't BarProtocol
assertFalse(delegate19_Bar is Derived)
assertFalse(delegate19_Any is Derived)
assertEquals(base, delegate19_Bar)
assertEquals(base, delegate19_Any)
}
private fun testAssignmentDerivedWithPropertyOverrideToDerivedWithPropertyOverride() {
val derived = DerivedWithPropertyOverride()
// WARNING: static type of backing field in CInterop KLib is `Base?`, but not expected `DerivedWithPropertyOverride?`. Comments below are related
val delegate10_Base: Base? = derived.delegate
assertEquals(null, delegate10_Base)
val delegate11_Bar: BarProtocol? = derived.delegate()
assertEquals(null, delegate11_Bar)
derived.delegate = derived
derived.setDelegate(derived)
val delegate12_Base: Base? = derived.delegate // static type is Base?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
assertTrue(delegate12_Base is Base)
assertTrue(delegate12_Base is FooProtocol)
assertTrue(delegate12_Base is BarProtocol)
assertTrue(delegate12_Base is DerivedWithPropertyOverride)
assertEquals(derived, delegate12_Base)
val delegate19_DerivedWithPropertyOverride: DerivedWithPropertyOverride? = derived.delegate()
assertTrue(delegate19_DerivedWithPropertyOverride is Base)
assertTrue(delegate19_DerivedWithPropertyOverride is FooProtocol)
assertTrue(delegate19_DerivedWithPropertyOverride is BarProtocol)
assertTrue(delegate19_DerivedWithPropertyOverride is DerivedWithPropertyOverride)
assertEquals(derived, delegate19_DerivedWithPropertyOverride)
val delegate13_Base: Base? = (derived as Base).delegate
assertTrue(delegate13_Base is Base)
assertTrue(delegate13_Base is FooProtocol)
assertTrue(delegate13_Base is BarProtocol)
assertTrue(delegate13_Base is DerivedWithPropertyOverride)
assertEquals(derived, delegate13_Base)
val delegate17_Base: Base? = (derived as Base).delegate() // static type is Base?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
assertTrue(delegate17_Base is Base)
assertTrue(delegate17_Base is FooProtocol)
assertTrue(delegate17_Base is BarProtocol)
assertTrue(delegate17_Base is DerivedWithPropertyOverride)
assertEquals(derived, delegate17_Base)
val delegate14_Foo: FooProtocol? = (derived as FooProtocol).delegate
assertTrue(delegate14_Foo is Base)
assertTrue(delegate14_Foo is FooProtocol)
assertTrue(delegate14_Foo is BarProtocol)
assertTrue(delegate14_Foo is DerivedWithPropertyOverride)
assertEquals(derived, delegate14_Foo)
val delegate18_Foo: FooProtocol? = (derived as FooProtocol).delegate() // static type is FooProtocol?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
assertTrue(delegate18_Foo is Base)
assertTrue(delegate18_Foo is FooProtocol)
assertTrue(delegate18_Foo is BarProtocol)
assertTrue(delegate18_Foo is DerivedWithPropertyOverride)
assertEquals(derived, delegate18_Foo)
val delegate15_Bar: BarProtocol? = (derived as BarProtocol).delegate
assertTrue(delegate15_Bar is Base)
assertTrue(delegate15_Bar is FooProtocol)
assertTrue(delegate15_Bar is BarProtocol)
assertTrue(delegate15_Bar is DerivedWithPropertyOverride)
assertEquals(derived, delegate15_Bar)
val delegate19_Bar: BarProtocol? = (derived as BarProtocol).delegate() // static type is BarProtocol?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
assertTrue(delegate19_Bar is Base)
assertTrue(delegate19_Bar is FooProtocol)
assertTrue(delegate19_Bar is BarProtocol)
assertTrue(delegate19_Bar is DerivedWithPropertyOverride)
assertEquals(derived, delegate19_Bar)
}
private fun testAssignmentDerivedWithPropertyOverrideToBase() {
val base = Base()
val delegate10_Base: Base? = base.delegate
assertEquals(null, delegate10_Base)
val delegate11_Base: Base? = base.delegate()
assertEquals(null, delegate11_Base)
val derived = DerivedWithPropertyOverride()
base.delegate = derived
base.setDelegate(derived)
val delegate12_Base: Base? = base.delegate
assertTrue(delegate12_Base is Base)
assertTrue(delegate12_Base is FooProtocol)
assertTrue(delegate12_Base is BarProtocol)
assertTrue(delegate12_Base is DerivedWithPropertyOverride)
assertEquals(derived, delegate12_Base)
val delegate19_Base: Base? = base.delegate()
assertTrue(delegate19_Base is Base)
assertTrue(delegate19_Base is FooProtocol)
assertTrue(delegate19_Base is BarProtocol)
assertTrue(delegate19_Base is DerivedWithPropertyOverride)
assertEquals(derived, delegate19_Base)
}
private fun testAssignmentBaseToDerivedWithPropertyOverride() {
val derived = DerivedWithPropertyOverride()
// WARNING: static type of backing field in CInterop KLib is `Base?`, but not expected `DerivedWithPropertyOverride?`. Comments below are related
val delegate10_Base: Base? = derived.delegate
assertEquals(null, delegate10_Base)
val delegate11_Bar: BarProtocol? = derived.delegate()
assertEquals(null, delegate11_Bar)
val base = Base()
derived.delegate = base
// derived.setDelegate(base) // argument type mismatch: actual type is 'library.Base', but 'library.DerivedWithPropertyOverride?' was expected, this deserves a diagnostic test
val delegate12_Base: Base? = derived.delegate // static type is Base?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
assertTrue(delegate12_Base is Base)
assertFalse(delegate12_Base is FooProtocol)
assertFalse(delegate12_Base is BarProtocol)
assertFalse(delegate12_Base is DerivedWithPropertyOverride)
assertEquals(base, delegate12_Base)
val delegate19_DerivedWithPropertyOverride: DerivedWithPropertyOverride? = derived.delegate()
assertTrue(delegate19_DerivedWithPropertyOverride is Base)
assertTrue(delegate19_DerivedWithPropertyOverride is FooProtocol)
assertTrue(delegate19_DerivedWithPropertyOverride is BarProtocol)
assertTrue(delegate19_DerivedWithPropertyOverride is DerivedWithPropertyOverride)
assertEquals(base, delegate19_DerivedWithPropertyOverride)
val delegate13_Base: Base? = (derived as Base).delegate
assertTrue(delegate13_Base is Base)
assertFalse(delegate13_Base is FooProtocol)
assertFalse(delegate13_Base is BarProtocol)
assertFalse(delegate13_Base is DerivedWithPropertyOverride)
assertEquals(base, delegate13_Base)
val delegate17_Base: Base? = (derived as Base).delegate() // static type is Base?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
assertTrue(delegate17_Base is Base)
assertFalse(delegate17_Base is FooProtocol)
assertFalse(delegate17_Base is BarProtocol)
assertFalse(delegate17_Base is DerivedWithPropertyOverride)
assertEquals(base, delegate17_Base)
val delegate14_Foo: FooProtocol? = (derived as FooProtocol).delegate
assertTrue(delegate14_Foo is Base)
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
// while at run-time, the type is Base, which isn't FooProtocol, and the "is" result is "false"
// assertFalse(delegate14_Foo is FooProtocol)
assertFalse(delegate14_Foo is BarProtocol)
assertFalse(delegate14_Foo is DerivedWithPropertyOverride)
assertEquals(base, delegate14_Foo)
val delegate18_Foo: FooProtocol? = (derived as FooProtocol).delegate() // static type is FooProtocol?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
assertTrue(delegate18_Foo is Base)
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
// while at run-time, the type is Base, which isn't FooProtocol, and the "is" result is "false"
// assertFalse(delegate18_Foo is FooProtocol)
assertFalse(delegate18_Foo is BarProtocol)
assertFalse(delegate18_Foo is DerivedWithPropertyOverride)
assertEquals(base, delegate18_Foo)
val delegate15_Bar: BarProtocol? = (derived as BarProtocol).delegate
assertTrue(delegate15_Bar is Base)
assertFalse(delegate15_Bar is FooProtocol)
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
// while at run-time, the type is Base, which isn't BarProtocol, and the "is" result is "false"
// assertFalse(delegate15_Bar is BarProtocol)
assertFalse(delegate15_Bar is DerivedWithPropertyOverride)
assertEquals(base, delegate15_Bar)
val delegate19_Bar: BarProtocol? = (derived as BarProtocol).delegate() // static type is BarProtocol?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
assertTrue(delegate19_Bar is Base)
assertFalse(delegate19_Bar is FooProtocol)
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
// while at run-time, the type is Base, which isn't BarProtocol, and the "is" result is "false"
// assertFalse(delegate19_Bar is BarProtocol)
assertFalse(delegate19_Bar is DerivedWithPropertyOverride)
assertEquals(base, delegate19_Bar)
}
private fun testGrandDerived() {
val grandDerived = GrandDerived()
val delegate10_Base: Base? = grandDerived.delegate
assertEquals(null, delegate10_Base)
val delegate11_Bar: BarProtocol? = grandDerived.delegate()
assertEquals(null, delegate11_Bar)
grandDerived.delegate = Base()
// grandDerived.setDelegate(Base()) // argument type mismatch: actual type is 'library.Base', but 'library.BarProtocol?' was expected, this deserves a diagnostic test
grandDerived.delegate = Derived()
grandDerived.setDelegate(Derived())
grandDerived.delegate = grandDerived
grandDerived.setDelegate(grandDerived)
val delegate12_Base: Base? = grandDerived.delegate
assertTrue(delegate12_Base is Base)
assertTrue(delegate12_Base is FooProtocol)
assertTrue(delegate12_Base is BarProtocol)
assertTrue(delegate12_Base is Derived)
assertTrue(delegate12_Base is GrandDerived)
assertEquals(grandDerived, delegate12_Base)
val delegate21_Bar: BarProtocol? = grandDerived.delegate()
assertTrue(delegate21_Bar is Base)
assertTrue(delegate21_Bar is FooProtocol)
assertTrue(delegate21_Bar is BarProtocol)
assertTrue(delegate21_Bar is Derived)
assertTrue(delegate21_Bar is GrandDerived)
assertEquals(grandDerived, delegate21_Bar)
val delegate13_Base: Base? = (grandDerived as Base).delegate
assertTrue(delegate13_Base is Base)
assertTrue(delegate13_Base is FooProtocol)
assertTrue(delegate13_Base is BarProtocol)
assertTrue(delegate13_Base is Derived)
assertTrue(delegate13_Base is GrandDerived)
assertEquals(grandDerived, delegate13_Base)
val delegate17_Base: Base? = (grandDerived as Base).delegate()
assertTrue(delegate17_Base is Base)
assertTrue(delegate17_Base is FooProtocol)
assertTrue(delegate17_Base is BarProtocol)
assertTrue(delegate17_Base is Derived)
assertTrue(delegate17_Base is GrandDerived)
assertEquals(grandDerived, delegate17_Base)
val delegate14_Foo: FooProtocol? = (grandDerived as FooProtocol).delegate
assertTrue(delegate14_Foo is Base)
assertTrue(delegate14_Foo is FooProtocol)
assertTrue(delegate14_Foo is BarProtocol)
assertTrue(delegate14_Foo is Derived)
assertTrue(delegate14_Foo is GrandDerived)
assertEquals(grandDerived, delegate14_Foo)
val delegate18_Foo: FooProtocol? = (grandDerived as FooProtocol).delegate()
assertTrue(delegate18_Foo is Base)
assertTrue(delegate18_Foo is FooProtocol)
assertTrue(delegate18_Foo is BarProtocol)
assertTrue(delegate18_Foo is Derived)
assertTrue(delegate18_Foo is GrandDerived)
assertEquals(grandDerived, delegate18_Foo)
val delegate15_Bar: BarProtocol? = (grandDerived as BarProtocol).delegate
assertTrue(delegate15_Bar is Base)
assertTrue(delegate15_Bar is FooProtocol)
assertTrue(delegate15_Bar is BarProtocol)
assertTrue(delegate15_Bar is Derived)
assertTrue(delegate15_Bar is GrandDerived)
assertEquals(grandDerived, delegate15_Bar)
val delegate19_Bar: BarProtocol? = (grandDerived as BarProtocol).delegate()
assertTrue(delegate19_Bar is Base)
assertTrue(delegate19_Bar is FooProtocol)
assertTrue(delegate19_Bar is BarProtocol)
assertTrue(delegate19_Bar is Derived)
assertTrue(delegate19_Bar is GrandDerived)
assertEquals(grandDerived, delegate19_Bar)
val delegate16_Base: Base? = (grandDerived as Derived).delegate
assertTrue(delegate16_Base is Base)
assertTrue(delegate16_Base is FooProtocol)
assertTrue(delegate16_Base is BarProtocol)
assertTrue(delegate16_Base is Derived)
assertTrue(delegate16_Base is GrandDerived)
assertEquals(grandDerived, delegate16_Base)
val delegate20_Bar: BarProtocol? = (grandDerived as Derived).delegate()
assertTrue(delegate20_Bar is Base)
assertTrue(delegate20_Bar is FooProtocol)
assertTrue(delegate20_Bar is BarProtocol)
assertTrue(delegate20_Bar is Derived)
assertTrue(delegate20_Bar is GrandDerived)
assertEquals(grandDerived, delegate20_Bar)
}
private fun testGrandDerivedWithPropertyOverride() {
val grandDerived = GrandDerivedWithPropertyOverride()
val delegate10_Base: Base? = grandDerived.delegate
assertEquals(null, delegate10_Base)
val delegate11_Bar: BarProtocol? = grandDerived.delegate()
assertEquals(null, delegate11_Bar)
grandDerived.delegate = Base()
// grandDerived.setDelegate(Base()) // argument type mismatch: actual type is 'library.Base', but 'library.DerivedWithPropertyOverride?' was expected, this deserves a diagnostic test
grandDerived.delegate = Derived()
// grandDerived.setDelegate(Derived()) // argument type mismatch: actual type is 'library.Derived', but 'library.DerivedWithPropertyOverride?' was expected, this deserves a diagnostic test
grandDerived.delegate = DerivedWithPropertyOverride()
grandDerived.setDelegate(DerivedWithPropertyOverride())
grandDerived.delegate = grandDerived
grandDerived.setDelegate(grandDerived)
val delegate12_Base: Base? = grandDerived.delegate
assertTrue(delegate12_Base is Base)
assertTrue(delegate12_Base is FooProtocol)
assertTrue(delegate12_Base is BarProtocol)
assertTrue(delegate12_Base is DerivedWithPropertyOverride)
assertTrue(delegate12_Base is GrandDerivedWithPropertyOverride)
assertEquals(grandDerived, delegate12_Base)
val delegate13_Base: Base? = (grandDerived as Base).delegate
assertTrue(delegate13_Base is Base)
assertTrue(delegate13_Base is FooProtocol)
assertTrue(delegate13_Base is BarProtocol)
assertTrue(delegate13_Base is DerivedWithPropertyOverride)
assertTrue(delegate13_Base is GrandDerivedWithPropertyOverride)
assertEquals(grandDerived, delegate13_Base)
val delegate14_Foo: FooProtocol? = (grandDerived as FooProtocol).delegate
assertTrue(delegate14_Foo is Base)
assertTrue(delegate14_Foo is FooProtocol)
assertTrue(delegate14_Foo is BarProtocol)
assertTrue(delegate14_Foo is DerivedWithPropertyOverride)
assertTrue(delegate14_Foo is GrandDerivedWithPropertyOverride)
assertEquals(grandDerived, delegate14_Foo)
val delegate15_Bar: BarProtocol? = (grandDerived as BarProtocol).delegate
assertTrue(delegate15_Bar is Base)
assertTrue(delegate15_Bar is FooProtocol)
assertTrue(delegate15_Bar is BarProtocol)
assertTrue(delegate15_Bar is DerivedWithPropertyOverride)
assertTrue(delegate15_Bar is GrandDerivedWithPropertyOverride)
assertEquals(grandDerived, delegate15_Bar)
val delegate16_DerivedWithPropertyOverride: DerivedWithPropertyOverride? = grandDerived.delegate()
assertTrue(delegate16_DerivedWithPropertyOverride is Base)
assertTrue(delegate16_DerivedWithPropertyOverride is FooProtocol)
assertTrue(delegate16_DerivedWithPropertyOverride is BarProtocol)
assertTrue(delegate16_DerivedWithPropertyOverride is DerivedWithPropertyOverride)
assertTrue(delegate16_DerivedWithPropertyOverride is GrandDerivedWithPropertyOverride)
assertEquals(grandDerived, delegate16_DerivedWithPropertyOverride)
val delegate17_Base: Base? = (grandDerived as Base).delegate()
assertTrue(delegate17_Base is Base)
assertTrue(delegate17_Base is FooProtocol)
assertTrue(delegate17_Base is BarProtocol)
assertTrue(delegate17_Base is DerivedWithPropertyOverride)
assertTrue(delegate17_Base is GrandDerivedWithPropertyOverride)
assertEquals(grandDerived, delegate17_Base)
val delegate18_FooProtocol: FooProtocol? = (grandDerived as FooProtocol).delegate()
assertTrue(delegate18_FooProtocol is Base)
assertTrue(delegate18_FooProtocol is FooProtocol)
assertTrue(delegate18_FooProtocol is BarProtocol)
assertTrue(delegate18_FooProtocol is DerivedWithPropertyOverride)
assertTrue(delegate18_FooProtocol is GrandDerivedWithPropertyOverride)
assertEquals(grandDerived, delegate18_FooProtocol)
val delegate19_BarProtocol: BarProtocol? = (grandDerived as BarProtocol).delegate()
assertTrue(delegate19_BarProtocol is Base)
assertTrue(delegate19_BarProtocol is FooProtocol)
assertTrue(delegate19_BarProtocol is BarProtocol)
assertTrue(delegate19_BarProtocol is DerivedWithPropertyOverride)
assertTrue(delegate19_BarProtocol is GrandDerivedWithPropertyOverride)
assertEquals(grandDerived, delegate19_BarProtocol)
val delegate20_DerivedWithPropertyOverride: DerivedWithPropertyOverride? = (grandDerived as DerivedWithPropertyOverride).delegate()
assertTrue(delegate20_DerivedWithPropertyOverride is Base)
assertTrue(delegate20_DerivedWithPropertyOverride is FooProtocol)
assertTrue(delegate20_DerivedWithPropertyOverride is BarProtocol)
assertTrue(delegate20_DerivedWithPropertyOverride is DerivedWithPropertyOverride)
assertTrue(delegate20_DerivedWithPropertyOverride is GrandDerivedWithPropertyOverride)
assertEquals(grandDerived, delegate20_DerivedWithPropertyOverride)
}
private fun testAssigmmentDerivedWithPropertyOverrideToGrandDerivedWithPropertyOverride() {
val grandDerived = GrandDerivedWithPropertyOverride()
val delegate10_Base: Base? = grandDerived.delegate
assertEquals(null, delegate10_Base)
val delegate11_Bar: BarProtocol? = grandDerived.delegate()
assertEquals(null, delegate11_Bar)
val derived = DerivedWithPropertyOverride()
grandDerived.delegate = derived
grandDerived.setDelegate(derived) // argument type mismatch: actual type is 'library.Base', but 'library.DerivedWithPropertyOverride?' was expected, this deserves a diagnostic test
val delegate12_Base: Base? = grandDerived.delegate
assertTrue(delegate12_Base is Base)
assertTrue(delegate12_Base is FooProtocol)
assertTrue(delegate12_Base is BarProtocol)
assertTrue(delegate12_Base is DerivedWithPropertyOverride)
assertFalse(delegate12_Base is GrandDerivedWithPropertyOverride)
assertEquals(derived, delegate12_Base)
val delegate13_Base: Base? = (grandDerived as Base).delegate
assertTrue(delegate13_Base is Base)
assertTrue(delegate13_Base is FooProtocol)
assertTrue(delegate13_Base is BarProtocol)
assertTrue(delegate13_Base is DerivedWithPropertyOverride)
assertFalse(delegate13_Base is GrandDerivedWithPropertyOverride)
assertEquals(derived, delegate13_Base)
val delegate14_Foo: FooProtocol? = (grandDerived as FooProtocol).delegate
assertTrue(delegate14_Foo is Base)
assertTrue(delegate14_Foo is FooProtocol)
assertTrue(delegate14_Foo is BarProtocol)
assertTrue(delegate14_Foo is DerivedWithPropertyOverride)
assertFalse(delegate14_Foo is GrandDerivedWithPropertyOverride)
assertEquals(derived, delegate14_Foo)
val delegate15_Bar: BarProtocol? = (grandDerived as BarProtocol).delegate
assertTrue(delegate15_Bar is Base)
assertTrue(delegate15_Bar is FooProtocol)
assertTrue(delegate15_Bar is BarProtocol)
assertTrue(delegate15_Bar is DerivedWithPropertyOverride)
assertFalse(delegate15_Bar is GrandDerivedWithPropertyOverride)
assertEquals(derived, delegate15_Bar)
val delegate16_DerivedWithPropertyOverride: DerivedWithPropertyOverride? = (grandDerived as DerivedWithPropertyOverride).delegate()
assertTrue(delegate16_DerivedWithPropertyOverride is Base)
assertTrue(delegate16_DerivedWithPropertyOverride is FooProtocol)
assertTrue(delegate16_DerivedWithPropertyOverride is BarProtocol)
assertTrue(delegate16_DerivedWithPropertyOverride is DerivedWithPropertyOverride)
assertFalse(delegate16_DerivedWithPropertyOverride is GrandDerivedWithPropertyOverride)
assertEquals(derived, delegate16_DerivedWithPropertyOverride)
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// DISABLE_NATIVE: isAppleTarget=false
// There is no GameController on watchOS.
// DISABLE_NATIVE: targetFamily=WATCHOS
// MODULE: cinterop
// FILE: kt59167.def
language=Objective-C
---
#import <GameController/GCDevice.h>
// We only need to touch the problematic header to trigger the problem,
// so actual code does not matter.
id<GCDevice> dummy() {
return nil;
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.test.*
import kt59167.*
fun box(): String {
assertNull(dummy())
return "OK"
}
@@ -0,0 +1,51 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop_kt63048
// FILE: kt63048.def
language = Objective-C
headers = kt63048.h
// FILE: kt63048.h
#import "Foundation/NSString.h"
#import "Foundation/NSObject.h"
@interface WithClassProperty : NSObject
-(instancetype) init;
@property (class, readonly, copy) NSString * stringProperty;
@end
// FILE: kt63048.m
#import "kt63048.h"
@implementation WithClassProperty : NSObject
-(instancetype) init {}
+ (NSString *) stringProperty { return @"153"; }
@end
// MODULE: main(cinterop_kt63048)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalObjCName::class)
import kt63048.*
import kotlin.test.assertEquals
@ObjCName("KotlinImplWithCompanionPropertyOverride")
class Impl : WithClassProperty() {
companion object : WithClassPropertyMeta() {
override fun stringProperty(): String? = "42"
}
}
@ObjCName("KotlinImplWithoutCompanionPropertyOverride")
class ImplWithoutOverride : WithClassProperty() {
companion object : WithClassPropertyMeta() {
}
}
fun box(): String {
assertEquals("42", Impl.stringProperty())
assertEquals("153", ImplWithoutOverride.stringProperty())
return "OK"
}
@@ -0,0 +1,31 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: kt63049.def
depends = Foundation
language = Objective-C
headers = kt63049.h
// FILE: kt63049.h
#import "Foundation/NSObject.h"
@interface KT63049 : NSObject
@end
// FILE: kt63049.m
#import "kt63049.h"
@implementation KT63049 : NSObject
@end
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalObjCName::class)
import kt63049.*
import kotlin.test.assertEquals
class Impl : KT63049() {
companion object : KT63049Meta() {
fun stringProperty(): String? = "OK"
}
}
fun box() = Impl.stringProperty()
@@ -0,0 +1,57 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// MODULE: lib1
// FILE: lib1.def
language=Objective-C
headers=lib1.h
// FILE: lib1.h
@class Foo;
@protocol Bar;
struct Baz;
// MODULE: lib2(lib1)
// FILE: lib2.def
language=Objective-C
headers=lib2.h
// FILE: lib2.h
#import "../lib1/lib1.h"
Foo* createFoo() {
return 0;
}
id<Bar> createBar() {
return 0;
}
struct Baz* createBaz() {
return 0;
}
// MODULE: main(lib1,lib2)
// FILE: main.kt
import kotlinx.cinterop.CPointer
import lib1.*
import lib2.*
import cnames.structs.Baz
import objcnames.classes.Foo
import objcnames.protocols.BarProtocol
@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
fun box(): String {
val foo: Foo? = createFoo()
if (foo !== null) return "FAIL 1"
val bar: BarProtocol? = createBar()
if (bar !== null) return "FAIL 2"
val baz: CPointer<Baz>? = createBaz()
if (baz !== null) return "FAIL 3"
return "OK"
}
@@ -0,0 +1,72 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: leakMemoryWithRunningThreadUnchecked.def
---
void test_RunInNewThread(void (*)());
// FILE: leakMemoryWithRunningThreadUnchecked.h
#ifdef __cplusplus
extern "C" {
#endif
void test_RunInNewThread(void (*)());
#ifdef __cplusplus
}
#endif
// FILE: leakMemoryWithRunningThreadUnchecked.cpp
#include "leakMemoryWithRunningThreadUnchecked.h"
#include <atomic>
#include <thread>
extern "C" void test_RunInNewThread(void (*f)()) {
std::atomic<bool> haveRun(false);
std::thread t([f, &haveRun]() {
f();
haveRun = true;
while (true) {}
});
t.detach();
while (!haveRun) {}
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(
kotlin.experimental.ExperimentalNativeApi::class,
kotlin.native.runtime.NativeRuntimeApi::class,
kotlinx.cinterop.ExperimentalForeignApi::class
)
import leakMemoryWithRunningThreadUnchecked.*
import kotlin.concurrent.AtomicInt
import kotlin.native.concurrent.*
import kotlin.native.Platform
import kotlin.test.*
import kotlinx.cinterop.*
val global = AtomicInt(0)
fun ensureInititalized() {
// Only needed with the legacy MM. TODO: Remove when legacy MM is gone.
kotlin.native.initRuntimeIfNeeded()
// Leak memory
StableRef.create(Any())
global.value = 1
}
fun box(): String {
Platform.isMemoryLeakCheckerActive = true
kotlin.native.runtime.Debugging.forceCheckedShutdown = false
assertTrue(global.value == 0)
// Created a thread, made sure Kotlin is initialized there.
test_RunInNewThread(staticCFunction(::ensureInititalized))
assertTrue(global.value == 1)
// Now exiting. With unchecked shutdown, we exit quietly, even though there're
// unfinished threads with runtimes.
return "OK"
}
@@ -0,0 +1,125 @@
// TARGET_BACKEND: NATIVE
// DISABLE_NATIVE: isAppleTarget=false
// LANGUAGE: +ImplicitSignedToUnsignedIntegerConversion
// MODULE: cinterop
// FILE: direct.def
language = Objective-C
headers = direct.h
headerFilter = direct.h
// FILE: direct.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
__attribute__((objc_runtime_name("CC")))
__attribute__((swift_name("CC")))
@interface CallingConventions : NSObject
+ (uint64_t)regular:(uint64_t)arg;
- (uint64_t)regular:(uint64_t)arg;
+ (uint64_t)direct:(uint64_t)arg __attribute__((objc_direct));
- (uint64_t)direct:(uint64_t)arg __attribute__((objc_direct));
@end
@interface CallingConventions(Ext)
+ (uint64_t)regularExt:(uint64_t)arg;
- (uint64_t)regularExt:(uint64_t)arg;
+ (uint64_t)directExt:(uint64_t)arg __attribute__((objc_direct));
- (uint64_t)directExt:(uint64_t)arg __attribute__((objc_direct));
@end
__attribute__((objc_runtime_name("CCH")))
__attribute__((swift_name("CCH")))
@interface CallingConventionsHeir : CallingConventions
@end
NS_ASSUME_NONNULL_END
// FILE: direct.m
#import "direct.h"
#define TEST_METHOD_IMPL(NAME) (uint64_t)NAME:(uint64_t)arg { return arg; }
@implementation CallingConventions : NSObject
+ TEST_METHOD_IMPL(regular);
- TEST_METHOD_IMPL(regular);
+ TEST_METHOD_IMPL(direct);
- TEST_METHOD_IMPL(direct);
@end
@implementation CallingConventions(Ext)
+ TEST_METHOD_IMPL(regularExt);
- TEST_METHOD_IMPL(regularExt);
+ TEST_METHOD_IMPL(directExt);
- TEST_METHOD_IMPL(directExt);
@end
@implementation CallingConventionsHeir
@end
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import direct.*
import kotlinx.cinterop.*
import kotlin.test.*
class CallingConventionsNativeHeir() : CallingConventions() {
// nothing
}
typealias CC = CallingConventions
typealias CCH = CallingConventionsHeir
typealias CCN = CallingConventionsNativeHeir
// KT-54610
fun box(): String {
autoreleasepool {
val cc = CC()
val cch = CCH()
val ccn = CCN()
assertEquals(42UL, CC.regular(42))
assertEquals(42UL, cc.regular(42))
assertEquals(42UL, CC.regularExt(42))
assertEquals(42UL, cc.regularExt(42))
assertEquals(42UL, CCH.regular(42))
assertEquals(42UL, cch.regular(42))
assertEquals(42UL, CCH.regularExt(42))
assertEquals(42UL, cch.regularExt(42))
assertEquals(42UL, ccn.regular(42UL))
assertEquals(42UL, ccn.regularExt(42UL))
assertEquals(42UL, CC.direct(42))
assertEquals(42UL, cc.direct(42))
assertEquals(42UL, CC.directExt(42))
assertEquals(42UL, cc.directExt(42))
assertEquals(42UL, CCH.direct(42))
assertEquals(42UL, cch .direct(42))
assertEquals(42UL, CCH.directExt(42))
assertEquals(42UL, cch .directExt(42))
assertEquals(42UL, ccn .direct(42UL))
assertEquals(42UL, ccn .directExt(42UL))
}
return "OK"
}
@@ -0,0 +1,113 @@
// TARGET_BACKEND: NATIVE
// `import objcnames` somehow works only with NATIVE_STANDALONE test directive
// NATIVE_STANDALONE
// DISABLE_NATIVE: isAppleTarget=false
// MODULE: a
// FILE: a.def
language = Objective-C
---
#import <Foundation/Foundation.h>
#include <stdio.h>
struct ForwardDeclaredStruct;
@class ForwardDeclaredClass;
@protocol ForwardDeclaredProtocol;
NSString* consumeProtocol(id<ForwardDeclaredProtocol> s) {
return [NSString stringWithUTF8String:"Protocol"];
}
NSString* consumeClass(ForwardDeclaredClass* s) {
return [NSString stringWithUTF8String:"Class"];
}
NSString* consumeStruct(struct ForwardDeclaredStruct* s) {
return [NSString stringWithUTF8String:"Struct"];
}
// MODULE: b
// FILE: b.def
language = Objective-C
headers = b.h
---
// FILE: b.h
#define NS_FORMAT_ARGUMENT(X)
#import <Foundation/Foundation.h>
@protocol ForwardDeclaredProtocol
@end
@interface ForwardDeclaredProtocolImpl : NSObject<ForwardDeclaredProtocol>
@end;
@interface ForwardDeclaredClass : NSObject
@end;
struct ForwardDeclaredStruct {};
id<ForwardDeclaredProtocol> produceProtocol();
ForwardDeclaredClass* produceClass();
struct ForwardDeclaredStruct* produceStruct();
// FILE: b.m
#import "b.h"
@implementation ForwardDeclaredProtocolImpl : NSObject
@end;
@implementation ForwardDeclaredClass : NSObject
@end;
id<ForwardDeclaredProtocol> produceProtocol() {
return [ForwardDeclaredProtocolImpl new];
}
ForwardDeclaredClass* produceClass() {
return [ForwardDeclaredClass new];
}
struct ForwardDeclaredStruct S;
struct ForwardDeclaredStruct* produceStruct() {
return &S;
}
// MODULE: lib(a)
// FILE: lib.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import cnames.structs.ForwardDeclaredStruct
import objcnames.classes.ForwardDeclaredClass
import objcnames.protocols.ForwardDeclaredProtocolProtocol
import a.*
import kotlinx.cinterop.*
fun testStruct(s: Any?) = consumeStruct(s as CPointer<ForwardDeclaredStruct>)
fun testClass(s: Any?) = consumeClass(s as ForwardDeclaredClass)
fun testProtocol(s: Any?) = consumeProtocol(s as ForwardDeclaredProtocolProtocol)
fun <T : ForwardDeclaredClass> testClass2Impl(s: Any?) = consumeClass(s as T)
fun <T : ForwardDeclaredProtocolProtocol> testProtocol2Impl(s: Any?) = consumeProtocol(s as T)
fun testClass2(s: Any?) = testClass2Impl<ForwardDeclaredClass>(s)
fun testProtocol2(s: Any?) = testProtocol2Impl<ForwardDeclaredProtocolProtocol>(s)
// MODULE: main(lib, b)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import a.*
import b.*
fun box(): String {
if (testStruct(produceStruct()) != "Struct") throw IllegalStateException()
if (testClass(produceClass()) != "Class") throw IllegalStateException()
if (testProtocol(produceProtocol()) != "Protocol") throw IllegalStateException()
if (testClass2(produceClass()) != "Class") throw IllegalStateException()
if (testProtocol2(produceProtocol()) != "Protocol") throw IllegalStateException()
return "OK"
}
@@ -0,0 +1,34 @@
// TARGET_BACKEND: NATIVE
// DISABLE_NATIVE: isAppleTarget=false
// FREE_CINTEROP_ARGS: -compiler-option -fmodule-map-file=$generatedSourcesDir/cinterop/module_library.modulemap
// MODULE: cinterop
// FILE: module_library.def
language = Objective-C
modules = module_library
// FILE: module_library.modulemap
module module_library {
umbrella header "module_library_umbrella.h"
export *
module * { export * }
}
// FILE: module_library_umbrella.h
#import <foo.h>
// FILE: foo.h
#define ANSWER 42
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import module_library.*
fun box(): String {
val answer = ANSWER
if (answer != 42)
return "FAIL: $answer"
return "OK"
}
@@ -0,0 +1,78 @@
// TARGET_BACKEND: NATIVE
// DISABLE_NATIVE: isAppleTarget=false
// Without a fix, fails in two-stage mode.
// The bug was accidentally fixed with lazy IR for caches, so testing it with this feature disabled:
// FREE_COMPILER_ARGS: -Xlazy-ir-for-caches=disable
// MODULE: cinterop
// FILE: objclib.def
language = Objective-C
headers = objclib.h
headerFilter = objclib.h **/NSObject.h **/NSDate.h **/NSUUID.h
// FILE: objclib.h
#import <Foundation/NSObject.h>
#import <Foundation/NSDate.h>
#import <Foundation/NSUUID.h>
@interface MyClass1 : NSObject
@end
@interface MyClass2 : NSObject
@end
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.reflect.*
import kotlin.test.*
import objclib.*
// https://youtrack.jetbrains.com/issue/KT-48816
open class Base<Ref> {
operator fun KProperty1<Ref, NSUUID>.getValue(ref: Base<Ref>, property: KProperty<*>): NSUUID? {
return null
}
operator fun KProperty1<Ref, NSDate>.getValue(ref: Base<Ref>, property: KProperty<*>): NSDate? {
return null
}
}
class Usage: Base<B>()
class B
// The compilation should fail with the above;
// but anyway try to actually use the code, just to ensure it doesn't get DCEd:
val B.uuid: NSUUID get() = fail()
val B.date: NSDate get() = fail()
fun test1() {
val uuidProperty = B::uuid
val dateProperty = B::date
val usage = Usage()
with(usage) {
assertNull(uuidProperty.getValue(usage, uuidProperty))
assertNull(dateProperty.getValue(usage, dateProperty))
}
}
// One more reproducer, just in case:
class Property<out R>
open class Base2 {
fun getValue(property: Property<MyClass1>) = null
fun getValue(property: Property<MyClass2>) = null
}
class Usage2 : Base2()
fun test2() {
val usage = Usage2()
assertNull(usage.getValue(Property<MyClass1>()))
assertNull(usage.getValue(Property<MyClass2>()))
}
fun box(): String {
test1()
test2()
return "OK"
}
@@ -0,0 +1,77 @@
// TARGET_BACKEND: NATIVE
// DISABLE_NATIVE: isAppleTarget=false
// The bug was accidentally fixed with lazy IR for caches, so testing it with this feature enabled, and disabled(in other test file):
// FREE_COMPILER_ARGS: -Xlazy-ir-for-caches=enable
// MODULE: cinterop
// FILE: objclib.def
language = Objective-C
headers = objclib.h
headerFilter = objclib.h **/NSObject.h **/NSDate.h **/NSUUID.h
// FILE: objclib.h
#import <Foundation/NSObject.h>
#import <Foundation/NSDate.h>
#import <Foundation/NSUUID.h>
@interface MyClass1 : NSObject
@end
@interface MyClass2 : NSObject
@end
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.reflect.*
import kotlin.test.*
import objclib.*
// https://youtrack.jetbrains.com/issue/KT-48816
open class Base<Ref> {
operator fun KProperty1<Ref, NSUUID>.getValue(ref: Base<Ref>, property: KProperty<*>): NSUUID? {
return null
}
operator fun KProperty1<Ref, NSDate>.getValue(ref: Base<Ref>, property: KProperty<*>): NSDate? {
return null
}
}
class Usage: Base<B>()
class B
// The compilation should fail with the above;
// but anyway try to actually use the code, just to ensure it doesn't get DCEd:
val B.uuid: NSUUID get() = fail()
val B.date: NSDate get() = fail()
fun test1() {
val uuidProperty = B::uuid
val dateProperty = B::date
val usage = Usage()
with(usage) {
assertNull(uuidProperty.getValue(usage, uuidProperty))
assertNull(dateProperty.getValue(usage, dateProperty))
}
}
// One more reproducer, just in case:
class Property<out R>
open class Base2 {
fun getValue(property: Property<MyClass1>) = null
fun getValue(property: Property<MyClass2>) = null
}
class Usage2 : Base2()
fun test2() {
val usage = Usage2()
assertNull(usage.getValue(Property<MyClass1>()))
assertNull(usage.getValue(Property<MyClass2>()))
}
fun box(): String {
test1()
test2()
return "OK"
}
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// `import objcnames` somehow works only with NATIVE_STANDALONE test directive
// NATIVE_STANDALONE
// The test checks no collision between kt49034.__darwin_fp_control and platform.posix.__darwin_fp_control
// The test makes sense only on Apple x64 targets, where `class __darwin_fp_control` present in posix platform lib
// DISABLE_NATIVE: isAppleTarget=false
// DISABLE_NATIVE: targetArchitecture=ARM64
// MODULE: cinterop
// FILE: kt49034.def
headers = kt49034.h
language = Objective-C
// FILE: kt49034.h
@class __darwin_fp_control;
void foo(__darwin_fp_control*);
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import objcnames.classes.__darwin_fp_control
open class C<T : kotlinx.cinterop.ObjCObject>
class D : C<__darwin_fp_control>()
fun box(): String {
println(D())
return "OK"
}
// FILE: checkPlatformDarwinFPControl.kt
import platform.posix.__darwin_fp_control
@@ -0,0 +1,58 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// The test depends on collision between kt49034.JSContext and platform.JavaScriptCore.JSContext
// DISABLE_NATIVE: isAppleTarget=false
// There is no JavaScriptCore on watchOS.
// DISABLE_NATIVE: targetFamily=WATCHOS
// MODULE: cinterop
// FILE: kt49034.def
headers = kt49034.h
// FILE: kt49034.h
#ifdef __cplusplus
extern "C" {
#endif
struct JSContext;
struct JSContext* bar();
#ifdef __cplusplus
}
#endif
// FILE: impl.c
#include "kt49034.h"
struct JSContext {
int field;
};
struct JSContext global = { 15 };
extern "C" struct JSContext* bar() {
return &global;
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kt49034.bar
import cnames.structs.JSContext
import kotlinx.cinterop.CPointer
fun baz(s: CPointer<JSContext>) {
println(s)
}
fun box(): String {
baz(bar()!!)
return "OK"
}
// FILE: checkPlatformJavaScriptCore.kt
import platform.JavaScriptCore.JSContext
@@ -0,0 +1,39 @@
// TARGET_BACKEND: NATIVE
// DISABLE_NATIVE: isAppleTarget=false
// FREE_CINTEROP_ARGS: -compiler-option -F$generatedSourcesDir/cinterop
// MODULE: cinterop
// FILE: objclib.def
language = Objective-C
modules = Foo
---
static int getDefInt() {
return 2;
}
static int getFrameworkIntFromDef() {
return getFrameworkInt();
}
// FILE: Foo.framework/Headers/Foo.h
static int getFrameworkInt() {
return 1;
}
// FILE: Foo.framework/Modules/module.modulemap
framework module Foo {
umbrella header "Foo.h"
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.test.*
import objclib.*
fun box(): String {
assertEquals(1, getFrameworkInt())
assertEquals(2, getDefInt())
assertEquals(1, getFrameworkIntFromDef())
return "OK"
}
@@ -0,0 +1,104 @@
// TARGET_BACKEND: NATIVE
// DISABLE_NATIVE: isAppleTarget=false
// MODULE: cinterop
// FILE: lib.def
language = Objective-C
headers = lib.h
headerFilter = lib.h
// FILE: lib.h
#import <Foundation/NSObject.h>
#import <Foundation/NSDate.h>
#import <Foundation/NSUUID.h>
@interface ObjCClass : NSObject
- (NSString*)fooWithArg:(int)arg arg2:(NSString*)arg2;
- (NSString*)fooWithArg:(int)ohNoOtherName name2:(NSString*)name2;
- (NSString*)fooWithArg:(int)arg name3:(NSString*)name3;
@end
// FILE: lib.m
#import "lib.h"
@implementation ObjCClass {
}
- (NSString*)fooWithArg:(int)arg arg2:(NSString*)arg2 {
return @"A";
}
- (NSString*)fooWithArg:(int)ohNoOtherName name2:(NSString*)name2 {
return @"B";
}
- (NSString*)fooWithArg:(int)arg name3:(NSString*)name3 {
return @"C";
}
@end
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
// required for K1
@file:Suppress("CONFLICTING_OVERLOADS", "UNRESOLVED_REFERENCE", "API_NOT_AVAILABLE")
import lib.ObjCClass
import kotlinx.cinterop.ObjCSignatureOverride
class OverrideAll : ObjCClass() {
@ObjCSignatureOverride
override fun fooWithArg(arg: Int, arg2: String?) = "D"
@ObjCSignatureOverride
override fun fooWithArg(ohNoOtherName: Int, name2: String?) = "E"
@ObjCSignatureOverride
override fun fooWithArg(arg: Int, name3: String?) = "F"
}
class OverrideNone : ObjCClass() {
}
class OverrideOne : ObjCClass() {
override fun fooWithArg(arg: Int, arg2: String?) = "G"
}
class OverrideWithDifferentFirstArgName : ObjCClass() {
@ObjCSignatureOverride
override fun fooWithArg(a: Int, arg2: String?) = "H"
@ObjCSignatureOverride
override fun fooWithArg(b: Int, name2: String?) = "I"
@ObjCSignatureOverride
override fun fooWithArg(c: Int, name3: String?) = "J"
}
fun test(x: ObjCClass, expected: String) {
val res = x.fooWithArg(arg = 0, arg2 = "") +
x.fooWithArg(ohNoOtherName = 0, name2="") +
x.fooWithArg(arg = 0, name3 = "")
if (res != expected) throw IllegalStateException("Fail ${x::class}: ${res} instead of $expected")
}
fun box(): String {
test(ObjCClass(), "ABC")
test(OverrideAll(), "DEF")
test(OverrideNone(), "ABC")
test(OverrideOne(), "GBC")
test(OverrideWithDifferentFirstArgName(), "HIJ")
// Also test non-virtual calls
val x1 = OverrideAll()
val res1 = x1.fooWithArg(arg = 0, arg2 = "") +
x1.fooWithArg(ohNoOtherName = 0, name2="") +
x1.fooWithArg(arg = 0, name3 = "")
if (res1 != "DEF") throw IllegalStateException("Fail OverrideAll non-virtual: ${res1} instead of DEF")
val x2 = OverrideNone()
val res2 = x2.fooWithArg(arg = 0, arg2 = "") +
x2.fooWithArg(ohNoOtherName = 0, name2="") +
x2.fooWithArg(arg = 0, name3 = "")
if (res2 != "ABC") throw IllegalStateException("Fail OverrideNone non-virtual: ${res2} instead of ABC")
return "OK"
}
@@ -0,0 +1,54 @@
// TARGET_BACKEND: NATIVE
// DISABLE_NATIVE: isAppleTarget=false
// MODULE: cinterop
// FILE: objclib.def
language = Objective-C
headers = objclib.h
headerFilter = objclib.h
// FILE: objclib.h
#import <objc/NSObject.h>
static NSObject* __weak globalObject = nil;
void setObject(NSObject* obj) {
globalObject = obj;
}
bool isObjectAlive() {
return globalObject != nil;
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(ObsoleteWorkersApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.native.concurrent.*
import kotlin.test.*
import kotlinx.cinterop.autoreleasepool
import objclib.*
fun box(): String {
val success = autoreleasepool {
run()
}
// Experimental MM supports arbitrary object sharing.
return if (success) "OK" else "FAIL"
}
private class NSObjectImpl : NSObject() {
var x = 111
}
fun run() = withWorker {
val obj = NSObjectImpl()
setObject(obj)
try {
execute(TransferMode.SAFE, {}) {
isObjectAlive()
}.result
} catch (e: Throwable) {
false
}
}
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2024 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: part1.part2.def
package package1
---
#define OK_STRING "OK"
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import package1.*
fun box(): String = OK_STRING
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2024 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: filename1.filename2.def
package package1.package2
---
#define OK_STRING "OK"
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import package1.package2.*
fun box(): String = OK_STRING
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2024 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: root1.root2.def
---
#define OK_STRING "OK"
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import root2.root1.*
fun box(): String = OK_STRING
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2024 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: packages.def
package package1
---
#define OK_STRING "OK"
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import package1.*
fun box(): String = OK_STRING
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2024 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: packages.def
package package1.package2
---
#define OK_STRING "OK"
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import package1.package2.*
fun box(): String = OK_STRING
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2024 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: root1.def
---
#define OK_STRING "OK"
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import root1.*
fun box(): String = OK_STRING
@@ -0,0 +1,52 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// NATIVE_STANDALONE
// MODULE: cinterop
// FILE: threadStates.def
language = C
---
void assertNativeThreadState();
void runCallback(void(*callback)(void)) {
assertNativeThreadState();
callback();
assertNativeThreadState();
}
// FILE: threadStates.cpp
#include <stdio.h>
#include <stdlib.h>
// Implemented in the runtime for test purposes.
extern "C" bool Kotlin_Debugging_isThreadStateNative();
extern "C" void assertNativeThreadState() {
if (!Kotlin_Debugging_isThreadStateNative()) {
printf("Incorrect thread state. Expected native thread state.");
abort();
}
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.native.runtime.Debugging
import kotlin.test.*
import kotlinx.cinterop.*
import threadStates.*
fun box(): String {
runCallback(staticCFunction { ->
assertRunnableThreadState()
})
assertRunnableThreadState()
return "OK"
}
fun assertRunnableThreadState() {
assertTrue(Debugging.isThreadStateRunnable)
}
@@ -0,0 +1,41 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// NATIVE_STANDALONE
// MODULE: cinterop
// FILE: threadStates.def
language = C
---
void runInNewThread(void(*callback)(void));
// FILE: threadStates.cpp
#include <thread>
extern "C" void runInNewThread(void(*callback)(void)) {
std::thread t([callback]() {
callback();
});
t.join();
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.native.runtime.Debugging
import kotlin.test.*
import kotlinx.cinterop.*
import threadStates.*
fun box(): String {
runInNewThread(staticCFunction { ->
assertRunnableThreadState()
})
return "OK"
}
fun assertRunnableThreadState() {
assertTrue(Debugging.isThreadStateRunnable)
}
@@ -0,0 +1,64 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// NATIVE_STANDALONE
// MODULE: cinterop
// FILE: threadStates.def
language = C
---
void assertNativeThreadState();
void runCallback(void(*callback)(void)) {
assertNativeThreadState();
callback();
assertNativeThreadState();
}
// FILE: threadStates.cpp
#include <stdio.h>
#include <stdlib.h>
// Implemented in the runtime for test purposes.
extern "C" bool Kotlin_Debugging_isThreadStateNative();
extern "C" void assertNativeThreadState() {
if (!Kotlin_Debugging_isThreadStateNative()) {
printf("Incorrect thread state. Expected native thread state.");
abort();
}
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.native.runtime.Debugging
import kotlin.test.*
import kotlinx.cinterop.staticCFunction
import threadStates.*
fun box(): String {
try {
runCallback(staticCFunction(::throwException))
} catch (e: CustomException) {
assertRunnableThreadState()
return "OK"
} catch (e: Throwable) {
assertRunnableThreadState()
fail("Wrong exception type: ${e.message}")
}
fail("No exception thrown")
}
fun assertRunnableThreadState() {
assertTrue(Debugging.isThreadStateRunnable)
}
class CustomException() : Exception()
fun throwException() {
assertRunnableThreadState()
throw CustomException()
}
@@ -0,0 +1,63 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// NATIVE_STANDALONE
// MODULE: cinterop
// FILE: threadStates.def
language = C
---
void assertNativeThreadState();
void runCallback(void(*callback)(void)) {
assertNativeThreadState();
callback();
assertNativeThreadState();
}
// FILE: threadStates.cpp
#include <stdio.h>
#include <stdlib.h>
// Implemented in the runtime for test purposes.
extern "C" bool Kotlin_Debugging_isThreadStateNative();
extern "C" void assertNativeThreadState() {
if (!Kotlin_Debugging_isThreadStateNative()) {
printf("Incorrect thread state. Expected native thread state.");
abort();
}
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.native.runtime.Debugging
import kotlin.test.*
import kotlinx.cinterop.staticCFunction
import threadStates.*
fun box(): String {
try {
runCallback(staticCFunction(::throwException))
} catch (e: CustomException) {
assertRunnableThreadState()
return "OK"
} finally {
assertRunnableThreadState()
}
fail("No exception thrown")
}
fun assertRunnableThreadState() {
assertTrue(Debugging.isThreadStateRunnable)
}
class CustomException() : Exception()
fun throwException() {
assertRunnableThreadState()
throw CustomException()
}
@@ -0,0 +1,63 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// NATIVE_STANDALONE
// MODULE: cinterop
// FILE: threadStates.def
language = C
---
void assertNativeThreadState();
void runCallback(void(*callback)(void)) {
assertNativeThreadState();
callback();
assertNativeThreadState();
}
// FILE: threadStates.cpp
#include <stdio.h>
#include <stdlib.h>
// Implemented in the runtime for test purposes.
extern "C" bool Kotlin_Debugging_isThreadStateNative();
extern "C" void assertNativeThreadState() {
if (!Kotlin_Debugging_isThreadStateNative()) {
printf("Incorrect thread state. Expected native thread state.");
abort();
}
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.native.runtime.Debugging
import kotlin.test.*
import kotlinx.cinterop.staticCFunction
import threadStates.*
fun box(): String {
try {
try {
runCallback(staticCFunction(::throwException))
} finally {
assertRunnableThreadState()
}
assertRunnableThreadState()
} catch (_: CustomException) {}
return "OK"
}
fun assertRunnableThreadState() {
assertTrue(Debugging.isThreadStateRunnable)
}
class CustomException() : Exception()
fun throwException() {
assertRunnableThreadState()
throw CustomException()
}
@@ -0,0 +1,25 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// NATIVE_STANDALONE
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.native.runtime.Debugging
import kotlin.test.*
import kotlinx.cinterop.*
fun box(): String {
val funPtr = staticCFunction { ->
assertRunnableThreadState()
}
assertRunnableThreadState()
funPtr()
assertRunnableThreadState()
return "OK"
}
fun assertRunnableThreadState() {
assertTrue(Debugging.isThreadStateRunnable)
}
@@ -0,0 +1,51 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// NATIVE_STANDALONE
// MODULE: cinterop
// FILE: threadStates.def
language = C
---
#include <stdint.h>
void assertNativeThreadState();
int32_t answer() {
assertNativeThreadState();
return 42;
}
// FILE: threadStates.cpp
#include <stdio.h>
#include <stdlib.h>
// Implemented in the runtime for test purposes.
extern "C" bool Kotlin_Debugging_isThreadStateNative();
extern "C" void assertNativeThreadState() {
if (!Kotlin_Debugging_isThreadStateNative()) {
printf("Incorrect thread state. Expected native thread state.");
abort();
}
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.native.runtime.Debugging
import kotlin.test.*
import kotlinx.cinterop.*
import threadStates.*
fun box(): String {
answer()
assertRunnableThreadState()
return "OK"
}
fun assertRunnableThreadState() {
assertTrue(Debugging.isThreadStateRunnable)
}
@@ -0,0 +1,67 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// NATIVE_STANDALONE
// MODULE: cinterop
// FILE: threadStates.def
language = C
---
void assertNativeThreadState();
void runCallback(void(*callback)(void)) {
assertNativeThreadState();
callback();
assertNativeThreadState();
}
// FILE: threadStates.cpp
#include <stdio.h>
#include <stdlib.h>
// Implemented in the runtime for test purposes.
extern "C" bool Kotlin_Debugging_isThreadStateNative();
extern "C" void assertNativeThreadState() {
if (!Kotlin_Debugging_isThreadStateNative()) {
printf("Incorrect thread state. Expected native thread state.");
abort();
}
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.native.runtime.Debugging
import kotlin.test.*
import kotlinx.cinterop.staticCFunction
import threadStates.*
fun box(): String {
try {
runCallback(staticCFunction { ->
assertRunnableThreadState()
runCallback(staticCFunction(::throwException))
})
} catch (e: CustomException) {
assertRunnableThreadState()
return "OK"
} catch (e: Throwable) {
assertRunnableThreadState()
fail("Wrong exception type: ${e.message}")
}
fail("No exception thrown")
}
fun assertRunnableThreadState() {
assertTrue(Debugging.isThreadStateRunnable)
}
class CustomException() : Exception()
fun throwException() {
assertRunnableThreadState()
throw CustomException()
}
@@ -0,0 +1,66 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// NATIVE_STANDALONE
// MODULE: cinterop
// FILE: threadStates.def
language = C
---
void assertNativeThreadState();
void runCallback(void(*callback)(void)) {
assertNativeThreadState();
callback();
assertNativeThreadState();
}
// FILE: threadStates.cpp
#include <stdio.h>
#include <stdlib.h>
// Implemented in the runtime for test purposes.
extern "C" bool Kotlin_Debugging_isThreadStateNative();
extern "C" void assertNativeThreadState() {
if (!Kotlin_Debugging_isThreadStateNative()) {
printf("Incorrect thread state. Expected native thread state.");
abort();
}
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.native.runtime.Debugging
import kotlin.test.*
import kotlinx.cinterop.staticCFunction
import threadStates.*
fun box(): String {
try {
runCallback(staticCFunction { ->
assertRunnableThreadState()
runCallback(staticCFunction(::throwException))
})
} catch (e: CustomException) {
assertRunnableThreadState()
return "OK"
} finally {
assertRunnableThreadState()
}
fail("No exception thrown")
}
fun assertRunnableThreadState() {
assertTrue(Debugging.isThreadStateRunnable)
}
class CustomException() : Exception()
fun throwException() {
assertRunnableThreadState()
throw CustomException()
}
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// TARGET_BACKEND: NATIVE
// NATIVE_STANDALONE
// MODULE: cinterop
// FILE: threadStates.def
language = C
---
#include <stdint.h>
void assertNativeThreadState();
void runCallback(void(*callback)(void)) {
assertNativeThreadState();
callback();
assertNativeThreadState();
}
int32_t answer() {
assertNativeThreadState();
return 42;
}
// FILE: threadStates.cpp
#include <stdio.h>
#include <stdlib.h>
// Implemented in the runtime for test purposes.
extern "C" bool Kotlin_Debugging_isThreadStateNative();
extern "C" void assertNativeThreadState() {
if (!Kotlin_Debugging_isThreadStateNative()) {
printf("Incorrect thread state. Expected native thread state.");
abort();
}
}
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlin.native.runtime.Debugging
import kotlin.test.*
import kotlinx.cinterop.*
import threadStates.*
fun box(): String {
runCallback(staticCFunction { ->
assertRunnableThreadState()
answer()
Unit
})
assertRunnableThreadState()
return "OK"
}
fun assertRunnableThreadState() {
assertTrue(Debugging.isThreadStateRunnable)
}
@@ -0,0 +1,29 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: toKString.def
---
const char* empty() { return ""; }
const char* foo() { return "foo"; }
const char* kuku() { return "куку"; }
const char* invalid_utf8() { return "\x85\xAF"; }
const char* zero_in_the_middle() { return "before zero\0after zero"; }
// MODULE: main(cinterop)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import toKString.*
import kotlinx.cinterop.*
import kotlin.native.*
import kotlin.test.*
fun box(): String {
assertEquals("", empty()!!.toKStringFromUtf8())
assertEquals("foo", foo()!!.toKStringFromUtf8())
assertEquals("куку", kuku()!!.toKStringFromUtf8())
assertEquals("\uFFFD\uFFFD", invalid_utf8()!!.toKStringFromUtf8())
assertEquals("before zero", zero_in_the_middle()!!.toKStringFromUtf8())
return "OK"
}