From 2987340edd46d95e4a93d6f650c4c1aeaccf3eed Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Fri, 7 Oct 2022 12:25:24 +0200 Subject: [PATCH] Get rid of unsafe cast function usages in :kotlin-native:backend.native --- build.gradle.kts | 1 - .../src/org/jetbrains/kotlin/cli/bc/K2Native.kt | 2 +- .../kotlin/backend/konan/FeaturedLibraries.kt | 3 +-- .../jetbrains/kotlin/backend/konan/KonanConfig.kt | 3 +-- .../src/org/jetbrains/kotlin/backend/konan/Linker.kt | 5 ++--- .../jetbrains/kotlin/backend/konan/ToplevelPhases.kt | 7 +++++-- .../backend/konan/descriptors/DescriptorUtils.kt | 12 +++++------- .../backend/konan/driver/StaticCompilerDriver.kt | 4 +--- .../jetbrains/kotlin/backend/konan/ir/NewIrUtils.kt | 7 ++----- .../kotlin/backend/konan/llvm/ContextUtils.kt | 10 +++++----- .../backend/konan/lower/InteropCallConvertors.kt | 9 ++++----- .../backend/konan/objcexport/ObjCExportNamer.kt | 6 +++--- 12 files changed, 30 insertions(+), 39 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index ae1a709d313..d25b68fabca 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -410,7 +410,6 @@ val projectsWithOptInToUnsafeCastFunctionsFromAddToStdLib by extra { ":js:js.tests", ":kotlin-build-common", ":kotlin-gradle-plugin", - ":kotlin-native:backend.native", ":kotlin-reflect-api", ":kotlin-scripting-jvm-host-test", ":native:frontend.native", diff --git a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt index 59a0c458b67..d4da9b7aacb 100644 --- a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt +++ b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt @@ -67,7 +67,7 @@ class K2Native : CLICompiler() { messageCollector.report(ERROR, "K2 does not support Native target right now") return ExitCode.COMPILATION_ERROR } - configuration.put(CLIConfigurationKeys.PHASE_CONFIG, createPhaseConfig(toplevelPhase, arguments, messageCollector)) + configuration.put(CLIConfigurationKeys.PHASE_CONFIG, createPhaseConfig(toplevelPhaseErased, arguments, messageCollector)) val enoughArguments = arguments.freeArgs.isNotEmpty() || arguments.isUsefulWithoutFreeArgs if (!enoughArguments) { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FeaturedLibraries.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FeaturedLibraries.kt index 9138796d0a4..e1bb3d29abb 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FeaturedLibraries.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FeaturedLibraries.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.library.SearchPathResolver import org.jetbrains.kotlin.library.isInterop import org.jetbrains.kotlin.library.toUnresolvedLibraries -import org.jetbrains.kotlin.utils.addToStdlib.cast internal fun Context.getExportedDependencies(): List = getDescriptorsFromLibraries((config.resolve.exportedLibraries + config.resolve.includedLibraries).toSet()) internal fun Context.getIncludedLibraryDescriptors(): List = getDescriptorsFromLibraries(config.resolve.includedLibraries.toSet()) @@ -165,7 +164,7 @@ private fun getFeaturedLibraries( val remainingFeaturedLibraries = featuredLibraryFiles.toMutableSet() val result = mutableListOf() //TODO: please add type checks before cast. - val libraries = resolvedLibraries.getFullList(null).cast>() + val libraries = resolvedLibraries.getFullList(null).map { it as KonanLibrary } for (library in libraries) { val libraryFile = library.libraryFile diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt index 770cec83a4d..26048445d74 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.konan.util.KonanHomeProvider import org.jetbrains.kotlin.konan.util.visibleName import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder import org.jetbrains.kotlin.util.removeSuffixIfPresent -import org.jetbrains.kotlin.utils.addToStdlib.cast class KonanConfig(val project: Project, val configuration: CompilerConfiguration) { @@ -241,7 +240,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration fun librariesWithDependencies(moduleDescriptor: ModuleDescriptor?): List { if (moduleDescriptor == null) error("purgeUnneeded() only works correctly after resolve is over, and we have successfully marked package files as needed or not needed.") - return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder).cast() + return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder).map { it as KonanLibrary } } val shouldCoverSources = configuration.getBoolean(KonanConfigKeys.COVERAGE) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt index 5f878902f82..1b38b9a43ee 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder import org.jetbrains.kotlin.library.uniqueName -import org.jetbrains.kotlin.utils.addToStdlib.cast internal fun determineLinkerOutput(context: Context): LinkerOutputKind = when (context.config.produce) { @@ -56,11 +55,11 @@ internal class CacheStorage(val context: Context) { private fun saveCacheBitcodeDependencies() { val bitcodeDependencies = context.config.resolvedLibraries .getFullList(TopologicalLibraryOrder) + .map { it as KonanLibrary } .filter { - require(it is KonanLibrary) context.generationState.llvmImports.bitcodeIsUsed(it) && it != context.config.cacheSupport.libraryToCache?.klib // Skip loops. - }.cast>() + } outputFiles.bitcodeDependenciesFile!!.writeLines(bitcodeDependencies.map { it.uniqueName }) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt index 3ab5673c218..feccc43e73d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt @@ -500,8 +500,7 @@ private val singleCompilation = NamedCompilerPhase( lower = entireBackend ) -// Have to hide Context as type parameter in order to expose toplevelPhase outside of this module. -val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase( +internal val toplevelPhase: CompilerPhase = namedUnitPhase( name = "Compiler", description = "The whole compilation process", lower = middleEnd then @@ -509,6 +508,10 @@ val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase( umbrellaCompilation ) +// Have to hide Context as type parameter in order to expose toplevelPhase outside of this module. +val toplevelPhaseErased: CompilerPhase<*, Unit, Unit> + get() = toplevelPhase + internal fun PhaseConfig.disableIf(phase: AnyNamedPhase, condition: Boolean) { if (condition) disable(phase) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt index ad3d47aefa1..3bee9ec526b 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt @@ -24,8 +24,6 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.jetbrains.kotlin.resolve.constants.StringValue import org.jetbrains.kotlin.resolve.descriptorUtil.module -import org.jetbrains.kotlin.utils.addToStdlib.cast -import org.jetbrains.kotlin.utils.addToStdlib.safeAs /** * List of all implemented interfaces (including those which implemented by a super class) @@ -271,20 +269,20 @@ internal fun IrClass.isFrozen(context: Context): Boolean { } } -fun IrConstructorCall.getAnnotationStringValue() = getValueArgument(0).safeAs>()?.value +fun IrConstructorCall.getAnnotationStringValue() = (getValueArgument(0) as? IrConst<*>)?.value as String? fun IrConstructorCall.getAnnotationStringValue(name: String): String { val parameter = symbol.owner.valueParameters.single { it.name.asString() == name } - return getValueArgument(parameter.index).cast>().value + return (getValueArgument(parameter.index) as IrConst<*>).value as String } fun AnnotationDescriptor.getAnnotationStringValue(name: String): String { - return argumentValue(name)?.safeAs()?.value ?: error("Expected value $name at annotation $this") + return (argumentValue(name) as? StringValue)?.value ?: error("Expected value $name at annotation $this") } -fun IrConstructorCall.getAnnotationValueOrNull(name: String): T? { +inline fun IrConstructorCall.getAnnotationValueOrNull(name: String): T? { val parameter = symbol.owner.valueParameters.atMostOne { it.name.asString() == name } - return parameter?.let { getValueArgument(it.index)?.let { (it.cast>()).value } } + return parameter?.let { getValueArgument(it.index)?.let { (it as IrConst<*>).value as T } } } fun IrFunction.externalSymbolOrThrow(): String? { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/StaticCompilerDriver.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/StaticCompilerDriver.kt index 6408d906f4a..7f4410de0a8 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/StaticCompilerDriver.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/StaticCompilerDriver.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.konan.driver import kotlinx.cinterop.usingJvmCInteropCallbacks import org.jetbrains.kotlin.analyzer.AnalysisResult -import org.jetbrains.kotlin.backend.common.phaser.CompilerPhase import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys @@ -15,7 +14,6 @@ import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.konan.util.usingNativeMemoryAllocator -import org.jetbrains.kotlin.utils.addToStdlib.cast /** * Static compiler uses statically-defined compilation pipeline and a single Context during whole compilation. @@ -46,7 +44,7 @@ internal class StaticCompilerDriver : CompilerDriver() { usingNativeMemoryAllocator { usingJvmCInteropCallbacks { try { - toplevelPhase.cast>().invokeToplevel(context.phaseConfig, context, Unit) + toplevelPhase.invokeToplevel(context.phaseConfig, context, Unit) } finally { context.disposeGenerationState() } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/NewIrUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/NewIrUtils.kt index 51976adf36c..f910726a45d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/NewIrUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/NewIrUtils.kt @@ -12,8 +12,6 @@ import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary import org.jetbrains.kotlin.backend.konan.llvm.KonanMetadata import org.jetbrains.kotlin.backend.konan.serialization.KonanFileMetadataSource import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleFragmentImpl -import org.jetbrains.kotlin.descriptors.DescriptorVisibilities -import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin @@ -29,7 +27,6 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.utils.addToStdlib.safeAs private fun IrClass.isClassTypeWithSignature(signature: IdSignature.CommonSignature): Boolean { return signature == symbol.signature @@ -59,8 +56,8 @@ inline fun IrDeclaration.getAnnotationArgumentValue(fqName: FqName, for (index in 0 until annotation.valueArgumentsCount) { val parameter = annotation.symbol.owner.valueParameters[index] if (parameter.name == Name.identifier(argumentName)) { - val actual = annotation.getValueArgument(index).safeAs>() - return actual?.value + val actual = annotation.getValueArgument(index) as? IrConst<*> ?: return null + return actual.value as T } } return null diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index ef789046321..aa5c7b47fa4 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -390,14 +390,14 @@ internal class Llvm(private val context: Context, val module: LLVMModuleRef) : R val nativeDependenciesToLink: List by lazy { context.config.resolvedLibraries .getFullList(TopologicalLibraryOrder) + .map { it as KonanLibrary } .filter { - require(it is KonanLibrary) (!it.isDefault && !context.config.purgeUserLibs) || imports.nativeDependenciesAreUsed(it) - }.cast>() + } } private val immediateBitcodeDependencies: List by lazy { - context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder).cast>() + context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder).map { it as KonanLibrary } .filter { (!it.isDefault && !context.config.purgeUserLibs) || imports.bitcodeIsUsed(it) } } @@ -440,12 +440,12 @@ internal class Llvm(private val context: Context, val module: LLVMModuleRef) : R // libraries list being returned is also toposorted. context.config.resolvedLibraries .getFullList(TopologicalLibraryOrder) - .cast>() + .map { it as KonanLibrary } .filter { it in set } } val bitcodeToLink: List by lazy { - (context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder).cast>()) + context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder).map { it as KonanLibrary } .filter { shouldContainBitcode(it) } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropCallConvertors.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropCallConvertors.kt index a4acf71d4ff..3bd2ed15bd8 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropCallConvertors.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropCallConvertors.kt @@ -22,7 +22,6 @@ import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.utils.addToStdlib.cast private class InteropCallContext( val symbols: KonanSymbols, @@ -329,7 +328,7 @@ private fun InteropCallContext.generateEnumVarValueAccess(callSite: IrCall): IrE private fun InteropCallContext.generateMemberAtAccess(callSite: IrCall): IrExpression { val accessor = callSite.symbol.owner val memberAt = accessor.getAnnotation(RuntimeNames.cStructMemberAt)!! - val offset = memberAt.getValueArgument(0).cast>().value + val offset = (memberAt.getValueArgument(0) as IrConst<*>).value as Long val fieldPointer = calculateFieldPointer(callSite.dispatchReceiver!!, offset) return when { accessor.isGetter -> { @@ -361,7 +360,7 @@ private fun InteropCallContext.generateMemberAtAccess(callSite: IrCall): IrExpre private fun InteropCallContext.generateArrayMemberAtAccess(callSite: IrCall): IrExpression { val accessor = callSite.symbol.owner val memberAt = accessor.getAnnotation(RuntimeNames.cStructArrayMemberAt)!! - val offset = memberAt.getValueArgument(0).cast>().value + val offset = (memberAt.getValueArgument(0) as IrConst<*>).value as Long val fieldPointer = calculateFieldPointer(callSite.dispatchReceiver!!, offset) return builder.irCall(symbols.interopInterpretCPointer).also { it.putValueArgument(0, fieldPointer) @@ -420,8 +419,8 @@ private fun InteropCallContext.readBits( private fun InteropCallContext.generateBitFieldAccess(callSite: IrCall): IrExpression { val accessor = callSite.symbol.owner val bitField = accessor.getAnnotation(RuntimeNames.cStructBitField)!! - val offset = bitField.getValueArgument(0).cast>().value - val size = bitField.getValueArgument(1).cast>().value + val offset = (bitField.getValueArgument(0) as IrConst<*>).value as Long + val size = (bitField.getValueArgument(1) as IrConst<*>).value as Int val base = builder.irCall(symbols.interopNativePointedRawPtrGetter).also { it.dispatchReceiver = callSite.dispatchReceiver!! } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt index 0dcf49fcba6..946ffdeee0f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt @@ -964,9 +964,9 @@ private fun DeclarationDescriptor.getObjCName(): ObjCName { var swiftName: String? = null var isExact = false annotations.findAnnotation(KonanFqNames.objCName)?.let { annotation -> - objCName = annotation.argumentValue("name")?.value?.cast() - swiftName = annotation.argumentValue("swiftName")?.value?.cast() - isExact = annotation.argumentValue("exact")?.value?.cast() ?: false + objCName = annotation.argumentValue("name")?.value as String? + swiftName = annotation.argumentValue("swiftName")?.value as String? + isExact = annotation.argumentValue("exact")?.value as Boolean? ?: false } return ObjCName(name.asString(), objCName, swiftName, isExact) }