blob: 03e7a92f26bb17ea6afd544e08ea29fa01de4e8b [file]
// TARGET_BACKEND: NATIVE
// DISABLE_NATIVE: isAppleTarget=false
// IGNORE_KLIB_RUNTIME_ERRORS_WITH_CUSTOM_FIRST_STAGE: Native:1.9,2.0,2.1,2.2,2.3,2.4
// IGNORE_KLIB_RUNTIME_ERRORS_WITH_CUSTOM_SECOND_STAGE: Native:1.9,2.0,2.1,2.2,2.3,2.4
// ^^^KT-77446 is fixed in 2.4.20-Beta1
// KT-77446: a Kotlin class subclassing an Objective-C class whose -init is declared unavailable
// must not crash when constructed via another initializer that internally dispatches through
// [self init]. AVPlayerItem.initWithAsset:automaticallyLoadedAssetKeys: is one real-world case;
// this test reproduces the same shape with a local ObjC base class so the test does not depend
// on AVFoundation host behavior.
// MODULE: objclib
// FILE: objclib.def
language = Objective-C
headers = objclib.h
headerFilter = objclib.h
// FILE: objclib.h
#import <Foundation/Foundation.h>
@interface ObjCBase : NSObject
- (instancetype)init __attribute__((unavailable));
- (instancetype)initWithValue:(int)value;
@property (nonatomic, readonly) int storedValue;
@end
// FILE: objclib.m
#import "objclib.h"
@implementation ObjCBase {
int _storedValue;
}
- (instancetype)init {
return [super init];
}
- (instancetype)initWithValue:(int)value {
self = [self init]; // This is the path that hit MissingInitImp before KT-77446 was fixed.
if (self) {
_storedValue = value;
}
return self;
}
- (int)storedValue {
return _storedValue;
}
@end
// MODULE: main(objclib)
// FILE: main.kt
@file:OptIn(kotlinx.cinterop.BetaInteropApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
import kotlinx.cinterop.ObjCObjectBase.OverrideInit
import objclib.ObjCBase
class KotlinSubclass : ObjCBase {
@OverrideInit
constructor(value: Int) : super(value = value)
}
fun box(): String {
val obj = KotlinSubclass(value = 42)
if (obj.storedValue() != 42) return "FAIL: storedValue=${obj.storedValue()}"
return "OK"
}