[K/N] Make cast to objc forward declaration unchecked
Before this commit it caused compiler crash. Unchecked cast warning to be done later. ^KT-59645
This commit is contained in:
committed by
Space Team
parent
1fdda8962d
commit
396cfb3956
+4
@@ -67,6 +67,10 @@ fun IrClass.isExternalObjCClass(): Boolean = this.isObjCClass() &&
|
||||
fun ClassDescriptor.isObjCForwardDeclaration(): Boolean =
|
||||
this.findPackage().fqName.startsWith(objcnamesForwardDeclarationsPackageName)
|
||||
|
||||
fun IrClass.isObjCForwardDeclaration(): Boolean =
|
||||
getPackageFragment().packageFqName.startsWith(objcnamesForwardDeclarationsPackageName)
|
||||
|
||||
|
||||
fun ClassDescriptor.isObjCMetaClass(): Boolean = this.getAllSuperClassifiers().any {
|
||||
it.fqNameSafe == objCClassFqName
|
||||
}
|
||||
|
||||
+12
-2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.konan.lower
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.konan.isObjCForwardDeclaration
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
@@ -52,9 +53,18 @@ internal class TypeOperatorLowering(val context: CommonBackendContext) : FileLow
|
||||
irFile.transformChildren(this, null)
|
||||
}
|
||||
|
||||
private fun effectiveCheckType(type: IrType) : IrType {
|
||||
val erasedType = type.erasure()
|
||||
return if (erasedType.classOrNull?.owner?.isObjCForwardDeclaration() == true) {
|
||||
context.irBuiltIns.anyType.mergeNullability(erasedType)
|
||||
} else {
|
||||
erasedType
|
||||
}
|
||||
}
|
||||
|
||||
private fun lowerCast(expression: IrTypeOperatorCall): IrExpression {
|
||||
builder.at(expression)
|
||||
val typeOperand = expression.typeOperand.erasure()
|
||||
val typeOperand = effectiveCheckType(expression.typeOperand)
|
||||
return if (typeOperand == expression.typeOperand) {
|
||||
expression
|
||||
} else {
|
||||
@@ -63,7 +73,7 @@ internal class TypeOperatorLowering(val context: CommonBackendContext) : FileLow
|
||||
}
|
||||
|
||||
private fun lowerSafeCast(expression: IrTypeOperatorCall): IrExpression {
|
||||
val typeOperand = expression.typeOperand.erasure()
|
||||
val typeOperand = effectiveCheckType(expression.typeOperand)
|
||||
|
||||
return builder.irBlock(expression) {
|
||||
+irLetS(expression.argument) { variable ->
|
||||
|
||||
@@ -4023,6 +4023,16 @@ createInterop("cForwardDeclarationsTwoLibs2") {
|
||||
}
|
||||
|
||||
if (PlatformInfo.isAppleTarget(project)) {
|
||||
createInterop("forwardDeclarationsCastA") {
|
||||
it.defFile "interop/forwardDeclarationsCast/a.def"
|
||||
}
|
||||
|
||||
createInterop("forwardDeclarationsCastB") {
|
||||
it.defFile "interop/forwardDeclarationsCast/b.def"
|
||||
it.headers "$projectDir/interop/forwardDeclarationsCast/b.h"
|
||||
it.extraOpts "-Xcompile-source", "$projectDir/interop/forwardDeclarationsCast/b.m"
|
||||
}
|
||||
|
||||
createInterop("objcSmoke") {
|
||||
it.defFile 'interop/objc/objcSmoke.def'
|
||||
it.headers "$projectDir/interop/objc/smoke.h"
|
||||
@@ -4155,7 +4165,7 @@ createInterop("exceptions_cCallback") {
|
||||
/**
|
||||
* Creates a task for the interop test. Configures runner and adds library and test build tasks.
|
||||
*/
|
||||
Task interopTestBase(String name, boolean multiFile, Closure<KonanInteropTest> configureClosure) {
|
||||
Task interopTestBase(String name, boolean multiFile, boolean interop2ForMainOnly, Closure<KonanInteropTest> configureClosure) {
|
||||
return KotlinNativeTestKt.createTest(project, name, KonanInteropTest) { task ->
|
||||
task.configure(configureClosure)
|
||||
if (task.enabled) {
|
||||
@@ -4173,7 +4183,7 @@ Task interopTestBase(String name, boolean multiFile, Closure<KonanInteropTest> c
|
||||
library(lib, targets: [targetName]) {
|
||||
libraries {
|
||||
artifact interopLib
|
||||
if (interopLib2 != null) artifact interopLib2
|
||||
if (interopLib2 != null && !interop2ForMainOnly) artifact interopLib2
|
||||
}
|
||||
srcFiles task.lib
|
||||
baseDir "$testOutputLocal/$name"
|
||||
@@ -4202,11 +4212,11 @@ Task interopTestBase(String name, boolean multiFile, Closure<KonanInteropTest> c
|
||||
}
|
||||
|
||||
Task interopTest(String name, Closure<KonanInteropTest> configureClosure) {
|
||||
return interopTestBase(name, false, configureClosure)
|
||||
return interopTestBase(name, false, false, configureClosure)
|
||||
}
|
||||
|
||||
Task interopTestMultifile(String name, Closure<KonanInteropTest> configureClosure) {
|
||||
return interopTestBase(name, true, configureClosure)
|
||||
return interopTestBase(name, true, false, configureClosure)
|
||||
}
|
||||
|
||||
standaloneTest("interop_objc_allocException") {
|
||||
@@ -4447,6 +4457,14 @@ interopTest("interop_kt51925") {
|
||||
useGoldenData = true
|
||||
}
|
||||
|
||||
interopTestBase("interop_forwardDeclarationsCast", false, true) {
|
||||
enabled = isAppleTarget(project)
|
||||
interop = 'forwardDeclarationsCastA'
|
||||
interop2 = 'forwardDeclarationsCastB'
|
||||
lib = 'interop/forwardDeclarationsCast/lib.kt'
|
||||
source = 'interop/forwardDeclarationsCast/main.kt'
|
||||
}
|
||||
|
||||
dynamicTest("interop_kt43502") {
|
||||
interop = "kt43502"
|
||||
source = "interop/kt43502/main.kt"
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
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"];
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
language = Objective-C
|
||||
---
|
||||
@@ -0,0 +1,18 @@
|
||||
#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();
|
||||
@@ -0,0 +1,21 @@
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
@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)
|
||||
@@ -0,0 +1,13 @@
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import a.*
|
||||
import b.*
|
||||
|
||||
|
||||
fun main() {
|
||||
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()
|
||||
}
|
||||
Reference in New Issue
Block a user