diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/commonAtomicTypes/overrideWithRawType.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/commonAtomicTypes/overrideWithRawType.kt index ac82f8ad69ec8..0774ea2f42ec1 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/commonAtomicTypes/overrideWithRawType.kt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/commonAtomicTypes/overrideWithRawType.kt @@ -9,7 +9,7 @@ import kotlin.concurrent.atomics.AtomicReference open class KotlinClass { - open fun foo(a: AtomicReference) { } + open fun foo(a: AtomicReference) { } } // FILE: JavaClass.java @@ -28,5 +28,5 @@ import kotlin.concurrent.atomics.AtomicReference fun usage(a: JavaClass) { a.foo(java.util.concurrent.atomic.AtomicReference("")) - a.foo(AtomicReference(1)) + a.foo(AtomicReference(1)) } \ No newline at end of file diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmTypeCheckers.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmTypeCheckers.kt index 2c57895a42f2d..746ee52a0931d 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmTypeCheckers.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmTypeCheckers.kt @@ -11,8 +11,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.type.FirResolvedTypeRefChecker import org.jetbrains.kotlin.fir.analysis.checkers.type.TypeCheckers import org.jetbrains.kotlin.fir.analysis.jvm.checkers.type.FirArrayOfNullableNothingTypeChecker import org.jetbrains.kotlin.fir.analysis.jvm.checkers.type.FirFunctionalTypeParameterNameChecker -import org.jetbrains.kotlin.fir.analysis.jvm.checkers.type.FirJvmAtomicReferenceArrayToPrimitiveTypeChecker -import org.jetbrains.kotlin.fir.analysis.jvm.checkers.type.FirJvmAtomicReferenceToPrimitiveTypeChecker import org.jetbrains.kotlin.fir.analysis.jvm.checkers.type.FirJvmModuleAccessibilityTypeChecker object JvmTypeCheckers : TypeCheckers() { @@ -23,8 +21,6 @@ object JvmTypeCheckers : TypeCheckers() { override val resolvedTypeRefCheckers: Set = setOf( FirDynamicUnsupportedChecker, FirJvmModuleAccessibilityTypeChecker, - FirJvmAtomicReferenceToPrimitiveTypeChecker, - FirJvmAtomicReferenceArrayToPrimitiveTypeChecker, FirArrayOfNullableNothingTypeChecker, ) } diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJvmAtomicReferenceToPrimitiveCallChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJvmAtomicReferenceToPrimitiveCallChecker.kt index b76a98074ecde..f190d23be98ed 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJvmAtomicReferenceToPrimitiveCallChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJvmAtomicReferenceToPrimitiveCallChecker.kt @@ -11,14 +11,16 @@ import org.jetbrains.kotlin.name.JvmStandardClassIds object FirJvmAtomicReferenceToPrimitiveCallChecker : AbstractAtomicReferenceToPrimitiveCallChecker( - JvmStandardClassIds.ATOMIC_REFERENCE_CLASS_ID, JvmStandardClassIds.atomicByPrimitive, MppCheckerKind.Platform, + JvmStandardClassIds.Callables.atomicReferenceCompareAndSet, + JvmStandardClassIds.Callables.atomicReferenceCompareAndExchange, ) object FirJvmAtomicReferenceArrayToPrimitiveCallChecker : AbstractAtomicReferenceToPrimitiveCallChecker( - JvmStandardClassIds.ATOMIC_REFERENCE_ARRAY_CLASS_ID, JvmStandardClassIds.atomicArrayByPrimitive, MppCheckerKind.Platform, + JvmStandardClassIds.Callables.atomicReferenceArrayCompareAndSet, + JvmStandardClassIds.Callables.atomicReferenceArrayCompareAndExchange, ) diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/type/FirJvmAtomicReferenceToPrimitiveTypeChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/type/FirJvmAtomicReferenceToPrimitiveTypeChecker.kt deleted file mode 100644 index 5b6684b02d4ca..0000000000000 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/type/FirJvmAtomicReferenceToPrimitiveTypeChecker.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2010-2025 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. - */ - -package org.jetbrains.kotlin.fir.analysis.jvm.checkers.type - -import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind -import org.jetbrains.kotlin.fir.analysis.checkers.type.AbstractAtomicReferenceToPrimitiveTypeChecker -import org.jetbrains.kotlin.name.JvmStandardClassIds - -object FirJvmAtomicReferenceToPrimitiveTypeChecker : - AbstractAtomicReferenceToPrimitiveTypeChecker( - JvmStandardClassIds.ATOMIC_REFERENCE_CLASS_ID, - JvmStandardClassIds.atomicByPrimitive, - MppCheckerKind.Platform - ) - -object FirJvmAtomicReferenceArrayToPrimitiveTypeChecker : - AbstractAtomicReferenceToPrimitiveTypeChecker( - JvmStandardClassIds.ATOMIC_REFERENCE_ARRAY_CLASS_ID, - JvmStandardClassIds.atomicArrayByPrimitive, - MppCheckerKind.Platform - ) diff --git a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeAtomicReferenceToPrimitiveCallChecker.kt b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeAtomicReferenceToPrimitiveCallChecker.kt index 083faf2d0c742..61d5a34da210a 100644 --- a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeAtomicReferenceToPrimitiveCallChecker.kt +++ b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeAtomicReferenceToPrimitiveCallChecker.kt @@ -7,21 +7,18 @@ package org.jetbrains.kotlin.fir.analysis.native.checkers import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind import org.jetbrains.kotlin.fir.analysis.checkers.expression.AbstractAtomicReferenceToPrimitiveCallChecker -import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.name.NativeRuntimeNames object FirNativeAtomicReferenceToPrimitiveCallChecker : AbstractAtomicReferenceToPrimitiveCallChecker( - NativeRuntimeNames.AtomicReference, NativeRuntimeNames.atomicByPrimitive, MppCheckerKind.Platform, + NativeRuntimeNames.Callables.atomicReferenceCompareAndSet, + NativeRuntimeNames.Callables.atomicReferenceCompareAndExchange, ) object FirNativeAtomicArrayToPrimitiveCallChecker : AbstractAtomicReferenceToPrimitiveCallChecker( - NativeRuntimeNames.AtomicArray, NativeRuntimeNames.atomicArrayByPrimitive, MppCheckerKind.Platform, -) { - override val FirBasedSymbol<*>.canInstantiateProblematicAtomicReference: Boolean - get() = this is FirFunctionSymbol<*> && callableId == NativeRuntimeNames.Callables.AtomicArray -} + NativeRuntimeNames.Callables.atomicArrayCompareAndSet, + NativeRuntimeNames.Callables.atomicArrayCompareAndExchange, +) diff --git a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeAtomicReferenceToPrimitiveTypeChecker.kt b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeAtomicReferenceToPrimitiveTypeChecker.kt deleted file mode 100644 index dd5b751adae52..0000000000000 --- a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeAtomicReferenceToPrimitiveTypeChecker.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2010-2025 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. - */ - -package org.jetbrains.kotlin.fir.analysis.native.checkers - -import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind -import org.jetbrains.kotlin.fir.analysis.checkers.type.AbstractAtomicReferenceToPrimitiveTypeChecker -import org.jetbrains.kotlin.name.NativeRuntimeNames - -object FirNativeAtomicReferenceToPrimitiveTypeChecker : - AbstractAtomicReferenceToPrimitiveTypeChecker( - NativeRuntimeNames.AtomicReference, - NativeRuntimeNames.atomicByPrimitive, - MppCheckerKind.Platform - ) - -object FirNativeAtomicArrayToPrimitiveTypeChecker : - AbstractAtomicReferenceToPrimitiveTypeChecker( - NativeRuntimeNames.AtomicArray, - NativeRuntimeNames.atomicArrayByPrimitive, - MppCheckerKind.Platform - ) diff --git a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/NativeTypeCheckers.kt b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/NativeTypeCheckers.kt index 621eb679cf32d..50122f827a68b 100644 --- a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/NativeTypeCheckers.kt +++ b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/NativeTypeCheckers.kt @@ -10,8 +10,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.type.* object NativeTypeCheckers : TypeCheckers() { override val resolvedTypeRefCheckers: Set get() = setOf( - FirNativeAtomicReferenceToPrimitiveTypeChecker, - FirNativeAtomicArrayToPrimitiveTypeChecker, FirDynamicUnsupportedChecker, ) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonTypeCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonTypeCheckers.kt index 84aca4b9e40b4..9d8560c5aa67c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonTypeCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonTypeCheckers.kt @@ -25,8 +25,6 @@ object CommonTypeCheckers : TypeCheckers() { FirContextualFunctionTypeChecker, FirKotlinActualAnnotationHasNoEffectInKotlinTypeChecker, FirProjectionRelationChecker, - FirCommonAtomicReferenceToPrimitiveTypeChecker, - FirCommonAtomicReferenceArrayToPrimitiveTypeChecker, FirArrayOfNothingTypeChecker, ) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt index 14ae4c46474c3..1a7f086da7ea5 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt @@ -56,7 +56,6 @@ import org.jetbrains.kotlin.types.model.TypeCheckerProviderContext import org.jetbrains.kotlin.util.ImplementationStatus import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.getChildren -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract @@ -986,7 +985,7 @@ private fun ConeKotlinType.containsMalformedArgument(context: CheckerContext, al it.type?.fullyExpandedType(context.session)?.isMalformedExpandedType(context, allowNullableNothing) == true } -fun checkAtomicReferenceAccess( +fun reportAtomicToPrimitiveProblematicAccess( type: ConeKotlinType, source: KtSourceElement?, atomicReferenceClassId: ClassId, @@ -997,7 +996,7 @@ fun checkAtomicReferenceAccess( val expanded = type.fullyExpandedType(context.session) val argument = expanded.typeArguments.firstOrNull()?.type ?: return - if (expanded.classId == atomicReferenceClassId && (argument.isPrimitive || argument.isValueClass(context.session))) { + if (argument.isPrimitive || argument.isValueClass(context.session)) { val candidate = appropriateCandidatesForArgument[argument.classId] reporter.reportOn(source, FirErrors.ATOMIC_REF_WITHOUT_CONSISTENT_IDENTITY, atomicReferenceClassId, argument, candidate, context) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCommonAtomicReferenceToPrimitiveCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCommonAtomicReferenceToPrimitiveCallChecker.kt index 883133f0ca639..27f95a4d25ac3 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCommonAtomicReferenceToPrimitiveCallChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCommonAtomicReferenceToPrimitiveCallChecker.kt @@ -7,47 +7,55 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind -import org.jetbrains.kotlin.fir.analysis.checkers.checkAtomicReferenceAccess +import org.jetbrains.kotlin.fir.analysis.checkers.reportAtomicToPrimitiveProblematicAccess import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.references.resolved -import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol +import org.jetbrains.kotlin.fir.resolve.fullyExpandedType +import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol +import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.resolvedType +import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.name.withClassId abstract class AbstractAtomicReferenceToPrimitiveCallChecker( - val atomicReferenceClassId: ClassId, val appropriateCandidatesForArgument: Map, mppKind: MppCheckerKind, + firstProblematicCallableId: CallableId, + vararg remainingProblematicCallableIds: CallableId, ) : FirFunctionCallChecker(mppKind) { + val problematicCallableIds: Set = setOf(firstProblematicCallableId, *remainingProblematicCallableIds) + override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) { - val callable = expression.calleeReference.resolved?.resolvedSymbol ?: return + val callable = expression.calleeReference.resolved?.resolvedSymbol as? FirFunctionSymbol<*> ?: return + val receiverType = expression.dispatchReceiver?.resolvedType?.fullyExpandedType(context.session) ?: return + val atomicReferenceClassId = receiverType.classId ?: return + val fullyExpandedCallableId = callable.callableId.withClassId(atomicReferenceClassId) - if (callable.canInstantiateProblematicAtomicReference) { - checkAtomicReferenceAccess( - expression.resolvedType, expression.source, + if (fullyExpandedCallableId in problematicCallableIds) { + reportAtomicToPrimitiveProblematicAccess( + receiverType, expression.source, atomicReferenceClassId, appropriateCandidatesForArgument, context, reporter ) } } - - open val FirBasedSymbol<*>.canInstantiateProblematicAtomicReference: Boolean - get() = this is FirConstructorSymbol } object FirCommonAtomicReferenceToPrimitiveCallChecker : AbstractAtomicReferenceToPrimitiveCallChecker( - StandardClassIds.AtomicReference, StandardClassIds.atomicByPrimitive, MppCheckerKind.Platform, + StandardClassIds.Callables.atomicReferenceCompareAndSet, + StandardClassIds.Callables.atomicReferenceCompareAndExchange, ) object FirCommonAtomicArrayToPrimitiveCallChecker : AbstractAtomicReferenceToPrimitiveCallChecker( - StandardClassIds.AtomicArray, StandardClassIds.atomicArrayByPrimitive, MppCheckerKind.Platform, + StandardClassIds.Callables.atomicArrayCompareAndSetAt, + StandardClassIds.Callables.atomicArrayCompareAndExchangeAt, ) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/type/FirCommonAtomicReferenceToPrimitiveTypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/type/FirCommonAtomicReferenceToPrimitiveTypeChecker.kt deleted file mode 100644 index 9dc94cbba4fc4..0000000000000 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/type/FirCommonAtomicReferenceToPrimitiveTypeChecker.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2010-2025 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. - */ - -package org.jetbrains.kotlin.fir.analysis.checkers.type - -import org.jetbrains.kotlin.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind -import org.jetbrains.kotlin.fir.analysis.checkers.checkAtomicReferenceAccess -import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.StandardClassIds - -abstract class AbstractAtomicReferenceToPrimitiveTypeChecker( - val atomicReferenceClassId: ClassId, - val appropriateCandidatesForArgument: Map, - mppKind: MppCheckerKind, -) : FirResolvedTypeRefChecker(mppKind) { - final override fun check(typeRef: FirResolvedTypeRef, context: CheckerContext, reporter: DiagnosticReporter) { - checkAtomicReferenceAccess( - typeRef.coneType, typeRef.source, - atomicReferenceClassId, appropriateCandidatesForArgument, - context, reporter, - ) - } -} - -object FirCommonAtomicReferenceToPrimitiveTypeChecker : - AbstractAtomicReferenceToPrimitiveTypeChecker( - StandardClassIds.AtomicReference, - StandardClassIds.atomicByPrimitive, - MppCheckerKind.Platform, - ) - -object FirCommonAtomicReferenceArrayToPrimitiveTypeChecker : - AbstractAtomicReferenceToPrimitiveTypeChecker( - StandardClassIds.AtomicArray, - StandardClassIds.atomicArrayByPrimitive, - MppCheckerKind.Platform, - ) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index 5f07f9a88157b..4ea03d96e7784 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -1494,7 +1494,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { ) map.put( ATOMIC_REF_WITHOUT_CONSISTENT_IDENTITY, - "''{0}'' uses identity equality, but ''{1}'' does not have a consistent identity.{2}", + "This call may have inconsistent results because ''{0}'' uses identity equality and ''{1}'' does not have a consistent identity.{2}", CLASS_ID_RELATIVE_NAME_ONLY, RENDER_TYPE, suggestIfNotNull(" Consider using ''{0}'' instead.", CLASS_ID_RELATIVE_NAME_ONLY), diff --git a/compiler/testData/diagnostics/nativeTests/errorProneAtomicArrayPrimitives.fir.kt b/compiler/testData/diagnostics/nativeTests/errorProneAtomicArrayPrimitives.fir.kt index d65aefb5fb441..6324d645220e9 100644 --- a/compiler/testData/diagnostics/nativeTests/errorProneAtomicArrayPrimitives.fir.kt +++ b/compiler/testData/diagnostics/nativeTests/errorProneAtomicArrayPrimitives.fir.kt @@ -11,17 +11,17 @@ import kotlin.concurrent.AtomicReference import kotlin.concurrent.AtomicArray fun testKotlin() { - val k = AtomicArray(1) { 127 } - k.compareAndSet(0, 127, 128) // true - k.compareAndSet(0, 128, 7777) // false + val k = AtomicArray(1) { 127 } + k.compareAndSet(0, 127, 128) // true + k.compareAndSet(0, 128, 7777) // false - val kk: AtomicArray + val kk: AtomicArray kk = k - val l = AtomicReference(127) - l.compareAndSet(127, 128) // true - l.compareAndSet(128, 7777) // false + val l = AtomicReference(127) + l.compareAndSet(127, 128) // true + l.compareAndSet(128, 7777) // false - val ll: AtomicReference + val ll: AtomicReference ll = l } diff --git a/compiler/testData/diagnostics/tests/atomicReferenceToValueClass.fir.kt b/compiler/testData/diagnostics/tests/atomicReferenceToValueClass.fir.kt index 3e6944396c4ff..9fca380459dfa 100644 --- a/compiler/testData/diagnostics/tests/atomicReferenceToValueClass.fir.kt +++ b/compiler/testData/diagnostics/tests/atomicReferenceToValueClass.fir.kt @@ -11,8 +11,8 @@ value class Box(val name: String) fun main() { val test = Box("Test") val rest = Box("Rest") - val box = AtomicReference(test) + val box = AtomicReference(test) - box.compareAndSet(test, rest) + box.compareAndSet(test, rest) println(box.get()) } diff --git a/compiler/testData/diagnostics/tests/errorProneAtomicArrayPrimitives.fir.kt b/compiler/testData/diagnostics/tests/errorProneAtomicArrayPrimitives.fir.kt index 9dfc5bb8e309a..c357cde9b3d6d 100644 --- a/compiler/testData/diagnostics/tests/errorProneAtomicArrayPrimitives.fir.kt +++ b/compiler/testData/diagnostics/tests/errorProneAtomicArrayPrimitives.fir.kt @@ -8,22 +8,22 @@ import java.util.concurrent.atomic.AtomicReferenceArray fun testJava() { - val j = AtomicReferenceArray(127) - j.compareAndSet(0, 127, 128) // true - j.compareAndSet(0, 128, 7777) // false + val j = AtomicReferenceArray(127) + j.compareAndSet(0, 127, 128) // true + j.compareAndSet(0, 128, 7777) // false - val jj: AtomicReferenceArray + val jj: AtomicReferenceArray jj = j } typealias JavaAtomicReferenceArray = AtomicReferenceArray fun testTypealiasedJava() { - val j = JavaAtomicReferenceArray(127) - j.compareAndSet(0, 127, 128) // true - j.compareAndSet(0, 128, 7777) // false + val j = JavaAtomicReferenceArray(127) + j.compareAndSet(0, 127, 128) // true + j.compareAndSet(0, 128, 7777) // false - val jj: JavaAtomicReferenceArray + val jj: JavaAtomicReferenceArray jj = j } @@ -34,21 +34,21 @@ fun testTypealiasedJava() { import kotlin.concurrent.atomics.AtomicArray fun testKotlin() { - val k = AtomicArray(arrayOf(127)) - k.compareAndSetAt(0, 127, 128) // true - k.compareAndSetAt(0, 128, 7777) // false + val k = AtomicArray(arrayOf(127)) + k.compareAndSetAt(0, 127, 128) // true + k.compareAndSetAt(0, 128, 7777) // false - val kk: AtomicArray + val kk: AtomicArray kk = k } typealias KotlinAtomicArray = AtomicArray fun testTypealiasedKotlin() { - val k = KotlinAtomicArray(arrayOf(127)) - k.compareAndSetAt(0, 127, 128) // true - k.compareAndSetAt(0, 128, 7777) // false + val k = KotlinAtomicArray(arrayOf(127)) + k.compareAndSetAt(0, 127, 128) // true + k.compareAndSetAt(0, 128, 7777) // false - val kk: KotlinAtomicArray + val kk: KotlinAtomicArray kk = k } diff --git a/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.fir.diag.txt b/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.fir.diag.txt index 6c7e8f7b4b82d..515b714d638a6 100644 --- a/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.fir.diag.txt +++ b/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.fir.diag.txt @@ -1,46 +1,22 @@ -/J.kt:(310,333): warning: 'AtomicReference' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicInteger' instead. +/J.kt:(385,407): warning: This call may have inconsistent results because 'AtomicReference' uses identity equality and 'Int' does not have a consistent identity. Consider using 'AtomicInteger' instead. -/J.kt:(347,367): warning: 'AtomicReference' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicInteger' instead. +/J.kt:(500,524): warning: This call may have inconsistent results because 'AtomicReference' uses identity equality and 'Long' does not have a consistent identity. Consider using 'AtomicLong' instead. -/J.kt:(395,420): warning: 'AtomicReference' uses identity equality, but 'Long' does not have a consistent identity. Consider using 'AtomicLong' instead. +/J.kt:(618,644): warning: This call may have inconsistent results because 'AtomicReference' uses identity equality and 'Char' does not have a consistent identity. -/J.kt:(434,455): warning: 'AtomicReference' uses identity equality, but 'Long' does not have a consistent identity. Consider using 'AtomicLong' instead. +/J.kt:(768,793): warning: This call may have inconsistent results because 'AtomicReferenceArray' uses identity equality and 'Int' does not have a consistent identity. Consider using 'AtomicIntegerArray' instead. -/J.kt:(483,509): warning: 'AtomicReference' uses identity equality, but 'Char' does not have a consistent identity. +/J.kt:(895,922): warning: This call may have inconsistent results because 'AtomicReferenceArray' uses identity equality and 'Long' does not have a consistent identity. Consider using 'AtomicLongArray' instead. -/J.kt:(523,544): warning: 'AtomicReference' uses identity equality, but 'Char' does not have a consistent identity. +/J.kt:(1030,1062): warning: This call may have inconsistent results because 'AtomicReferenceArray' uses identity equality and 'Boolean' does not have a consistent identity. +/K.kt:(337,361): warning: This call may have inconsistent results because 'AtomicReference' uses identity equality and 'Int' does not have a consistent identity. Consider using 'AtomicInt' instead. -/J.kt:(596,624): warning: 'AtomicReferenceArray' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicIntegerArray' instead. +/K.kt:(450,476): warning: This call may have inconsistent results because 'AtomicReference' uses identity equality and 'Long' does not have a consistent identity. Consider using 'AtomicLong' instead. -/J.kt:(638,663): warning: 'AtomicReferenceArray' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicIntegerArray' instead. +/K.kt:(569,598): warning: This call may have inconsistent results because 'AtomicReference' uses identity equality and 'Boolean' does not have a consistent identity. Consider using 'AtomicBoolean' instead. -/J.kt:(691,720): warning: 'AtomicReferenceArray' uses identity equality, but 'Long' does not have a consistent identity. Consider using 'AtomicLongArray' instead. +/K.kt:(712,741): warning: This call may have inconsistent results because 'AtomicArray' uses identity equality and 'Int' does not have a consistent identity. Consider using 'AtomicIntArray' instead. -/J.kt:(734,760): warning: 'AtomicReferenceArray' uses identity equality, but 'Long' does not have a consistent identity. Consider using 'AtomicLongArray' instead. +/K.kt:(831,862): warning: This call may have inconsistent results because 'AtomicArray' uses identity equality and 'Long' does not have a consistent identity. Consider using 'AtomicLongArray' instead. -/J.kt:(788,820): warning: 'AtomicReferenceArray' uses identity equality, but 'Boolean' does not have a consistent identity. - -/J.kt:(834,863): warning: 'AtomicReferenceArray' uses identity equality, but 'Boolean' does not have a consistent identity. -/K.kt:(259,279): warning: 'AtomicReference' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicInt' instead. - -/K.kt:(293,313): warning: 'AtomicReference' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicInt' instead. - -/K.kt:(341,362): warning: 'AtomicReference' uses identity equality, but 'Long' does not have a consistent identity. Consider using 'AtomicLong' instead. - -/K.kt:(376,397): warning: 'AtomicReference' uses identity equality, but 'Long' does not have a consistent identity. Consider using 'AtomicLong' instead. - -/K.kt:(425,447): warning: 'AtomicReference' uses identity equality, but 'Boolean' does not have a consistent identity. Consider using 'AtomicBoolean' instead. - -/K.kt:(461,485): warning: 'AtomicReference' uses identity equality, but 'Boolean' does not have a consistent identity. Consider using 'AtomicBoolean' instead. - -/K.kt:(539,564): warning: 'AtomicArray' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicIntArray' instead. - -/K.kt:(578,594): warning: 'AtomicArray' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicIntArray' instead. - -/K.kt:(622,648): warning: 'AtomicArray' uses identity equality, but 'Long' does not have a consistent identity. Consider using 'AtomicLongArray' instead. - -/K.kt:(662,679): warning: 'AtomicArray' uses identity equality, but 'Long' does not have a consistent identity. Consider using 'AtomicLongArray' instead. - -/K.kt:(707,734): warning: 'AtomicArray' uses identity equality, but 'Boolean' does not have a consistent identity. - -/K.kt:(748,768): warning: 'AtomicArray' uses identity equality, but 'Boolean' does not have a consistent identity. +/K.kt:(956,990): warning: This call may have inconsistent results because 'AtomicArray' uses identity equality and 'Boolean' does not have a consistent identity. diff --git a/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.fir.kt b/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.fir.kt index 7417410441bdb..902540e3532d1 100644 --- a/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.fir.kt +++ b/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.fir.kt @@ -10,31 +10,37 @@ import java.util.concurrent.atomic.AtomicReferenceArray import java.util.concurrent.atomic.AtomicReference fun testJavaReference() { - val ji = AtomicReference(1) - val jji: AtomicReference + val ji = AtomicReference(1) + val jji: AtomicReference jji = ji + ji.compareAndSet(1, 2) - val jl = AtomicReference(1L) - val jjl: AtomicReference + val jl = AtomicReference(1L) + val jjl: AtomicReference jjl = jl + jl.compareAndSet(1L, 2L) - val jb = AtomicReference('c') - val jjb: AtomicReference + val jb = AtomicReference('c') + val jjb: AtomicReference jjb = jb + jb.compareAndSet('c', 'd') } fun testJavaArray() { - val ji = AtomicReferenceArray(1) - val jji: AtomicReferenceArray + val ji = AtomicReferenceArray(1) + val jji: AtomicReferenceArray jji = ji + ji.compareAndSet(0, 1, 2) - val jl = AtomicReferenceArray(1) - val jjl: AtomicReferenceArray + val jl = AtomicReferenceArray(1) + val jjl: AtomicReferenceArray jjl = jl + jl.compareAndSet(0, 1L, 2L) - val jb = AtomicReferenceArray(1) - val jjb: AtomicReferenceArray + val jb = AtomicReferenceArray(1) + val jjb: AtomicReferenceArray jjb = jb + jb.compareAndSet(0, true, false) } // FILE: K.kt @@ -45,29 +51,35 @@ import kotlin.concurrent.atomics.AtomicReference import kotlin.concurrent.atomics.AtomicArray fun testKotlinReference() { - val ki = AtomicReference(127) - val kki: AtomicReference + val ki = AtomicReference(127) + val kki: AtomicReference kki = ki + ki.compareAndSet(127, 2) - val kl = AtomicReference(127L) - val kkl: AtomicReference + val kl = AtomicReference(127L) + val kkl: AtomicReference kkl = kl + kl.compareAndSet(127L, 2L) - val kb = AtomicReference(false) - val kkb: AtomicReference + val kb = AtomicReference(false) + val kkb: AtomicReference kkb = kb + kb.compareAndSet(false, true) } fun testKotlinArray() { - val ki = AtomicArray(arrayOf(127)) - val kki: AtomicArray + val ki = AtomicArray(arrayOf(127)) + val kki: AtomicArray kki = ki + ki.compareAndSetAt(0, 127, 2) - val kl = AtomicArray(arrayOf(127L)) - val kkl: AtomicArray + val kl = AtomicArray(arrayOf(127L)) + val kkl: AtomicArray kkl = kl + kl.compareAndSetAt(0, 127L, 2L) - val kb = AtomicArray(arrayOf(false)) - val kkb: AtomicArray + val kb = AtomicArray(arrayOf(false)) + val kkb: AtomicArray kkb = kb + kb.compareAndSetAt(0, false, true) } diff --git a/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.kt b/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.kt index 4ed7ff63d6b6e..8b9342cd78dfe 100644 --- a/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.kt +++ b/compiler/testData/diagnostics/tests/errorProneAtomicArraySuggestions.kt @@ -13,28 +13,34 @@ fun testJavaReference() { val ji = AtomicReference(1) val jji: AtomicReference jji = ji + ji.compareAndSet(1, 2) val jl = AtomicReference(1L) val jjl: AtomicReference jjl = jl + jl.compareAndSet(1L, 2L) val jb = AtomicReference('c') val jjb: AtomicReference jjb = jb + jb.compareAndSet('c', 'd') } fun testJavaArray() { val ji = AtomicReferenceArray(1) val jji: AtomicReferenceArray jji = ji + ji.compareAndSet(0, 1, 2) val jl = AtomicReferenceArray(1) val jjl: AtomicReferenceArray jjl = jl + jl.compareAndSet(0, 1L, 2L) val jb = AtomicReferenceArray(1) val jjb: AtomicReferenceArray jjb = jb + jb.compareAndSet(0, true, false) } // FILE: K.kt @@ -48,26 +54,32 @@ fun testKotlinReference() { val ki = AtomicReference(127) val kki: AtomicReference kki = ki + ki.compareAndSet(127, 2) val kl = AtomicReference(127L) val kkl: AtomicReference kkl = kl + kl.compareAndSet(127L, 2L) val kb = AtomicReference(false) val kkb: AtomicReference kkb = kb + kb.compareAndSet(false, true) } fun testKotlinArray() { val ki = AtomicArray(arrayOf(127)) val kki: AtomicArray kki = ki + ki.compareAndSetAt(0, 127, 2) val kl = AtomicArray(arrayOf(127L)) val kkl: AtomicArray kkl = kl + kl.compareAndSetAt(0, 127L, 2L) val kb = AtomicArray(arrayOf(false)) val kkb: AtomicArray kkb = kb + kb.compareAndSetAt(0, false, true) } diff --git a/compiler/testData/diagnostics/tests/errorProneAtomicReferencePrimitives.fir.kt b/compiler/testData/diagnostics/tests/errorProneAtomicReferencePrimitives.fir.kt index 2098285b7fe85..2e3153182347e 100644 --- a/compiler/testData/diagnostics/tests/errorProneAtomicReferencePrimitives.fir.kt +++ b/compiler/testData/diagnostics/tests/errorProneAtomicReferencePrimitives.fir.kt @@ -8,22 +8,22 @@ import java.util.concurrent.atomic.AtomicReference fun testJava() { - val j = AtomicReference(127) - j.compareAndSet(127, 128) // true - j.compareAndSet(128, 7777) // false + val j = AtomicReference(127) + j.compareAndSet(127, 128) // true + j.compareAndSet(128, 7777) // false - val jj: AtomicReference + val jj: AtomicReference jj = j } typealias JavaAtomicReference = AtomicReference fun testTypealiasedJava() { - val j = JavaAtomicReference(127) - j.compareAndSet(127, 128) // true - j.compareAndSet(128, 7777) // false + val j = JavaAtomicReference(127) + j.compareAndSet(127, 128) // true + j.compareAndSet(128, 7777) // false - val jj: JavaAtomicReference + val jj: JavaAtomicReference jj = j } @@ -34,21 +34,21 @@ fun testTypealiasedJava() { import kotlin.concurrent.atomics.AtomicReference fun testKotlin() { - val k = AtomicReference(127) - k.compareAndSet(127, 128) // true - k.compareAndSet(128, 7777) // false + val k = AtomicReference(127) + k.compareAndSet(127, 128) // true + k.compareAndSet(128, 7777) // false - val kk: AtomicReference + val kk: AtomicReference kk = k } typealias KotlinAtomicReference = AtomicReference fun testTypealiasedKotlin() { - val k = KotlinAtomicReference(127) - k.compareAndSet(127, 128) // true - k.compareAndSet(128, 7777) // false + val k = KotlinAtomicReference(127) + k.compareAndSet(127, 128) // true + k.compareAndSet(128, 7777) // false - val kk: KotlinAtomicReference + val kk: KotlinAtomicReference kk = k } diff --git a/compiler/testData/diagnostics/tests/multiplatform/errorProneAtomicReferencePrimitivesInKMP.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/errorProneAtomicReferencePrimitivesInKMP.fir.kt index ea495f8dc0966..180756be1e1cc 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/errorProneAtomicReferencePrimitivesInKMP.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/errorProneAtomicReferencePrimitivesInKMP.fir.kt @@ -11,11 +11,11 @@ import kotlin.concurrent.atomics.AtomicReference fun commonTestKotlin() { - val k = AtomicReference(127) - k.compareAndSet(127, 128) // true - k.compareAndSet(128, 7777) // false + val k = AtomicReference(127) + k.compareAndSet(127, 128) // true + k.compareAndSet(128, 7777) // false - val kk: AtomicReference + val kk: AtomicReference kk = k } @@ -24,11 +24,11 @@ expect class KotlinAtomicReference(value: T) { } fun commonTypealiasedKotlin() { - val k = KotlinAtomicReference(127) - k.compareAndSet(127, 128) // true - k.compareAndSet(128, 7777) // false + val k = KotlinAtomicReference(127) + k.compareAndSet(127, 128) // true + k.compareAndSet(128, 7777) // false - val kk: KotlinAtomicReference + val kk: KotlinAtomicReference kk = k } @@ -40,22 +40,22 @@ fun commonTypealiasedKotlin() { import kotlin.concurrent.atomics.AtomicReference fun testKotlin() { - val k = AtomicReference(127) - k.compareAndSet(127, 128) // true - k.compareAndSet(128, 7777) // false + val k = AtomicReference(127) + k.compareAndSet(127, 128) // true + k.compareAndSet(128, 7777) // false - val kk: AtomicReference + val kk: AtomicReference kk = k } actual typealias KotlinAtomicReference = AtomicReference fun testTypealiasedKotlin() { - val k = KotlinAtomicReference(127) - k.compareAndSet(127, 128) // true - k.compareAndSet(128, 7777) // false + val k = KotlinAtomicReference(127) + k.compareAndSet(127, 128) // true + k.compareAndSet(128, 7777) // false - val kk: KotlinAtomicReference + val kk: KotlinAtomicReference kk = k } @@ -64,10 +64,10 @@ fun testTypealiasedKotlin() { import java.util.concurrent.atomic.AtomicReference fun testJava() { - val j = AtomicReference(127) - j.compareAndSet(127, 128) // true - j.compareAndSet(128, 7777) // false + val j = AtomicReference(127) + j.compareAndSet(127, 128) // true + j.compareAndSet(128, 7777) // false - val jj: AtomicReference + val jj: AtomicReference jj = j } diff --git a/compiler/testData/diagnostics/tests/multiplatform/errorProneAtomicReferencePrimitivesInKMP.ll.kt b/compiler/testData/diagnostics/tests/multiplatform/errorProneAtomicReferencePrimitivesInKMP.ll.kt index 294de1dc0a3b5..318f092a785c1 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/errorProneAtomicReferencePrimitivesInKMP.ll.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/errorProneAtomicReferencePrimitivesInKMP.ll.kt @@ -11,11 +11,11 @@ import kotlin.concurrent.atomics.AtomicReference fun commonTestKotlin() { - val k = AtomicReference(127) - k.compareAndSet(127, 128) // true - k.compareAndSet(128, 7777) // false + val k = AtomicReference(127) + k.compareAndSet(127, 128) // true + k.compareAndSet(128, 7777) // false - val kk: AtomicReference + val kk: AtomicReference kk = k } @@ -40,22 +40,22 @@ fun commonTypealiasedKotlin() { import kotlin.concurrent.atomics.AtomicReference fun testKotlin() { - val k = AtomicReference(127) - k.compareAndSet(127, 128) // true - k.compareAndSet(128, 7777) // false + val k = AtomicReference(127) + k.compareAndSet(127, 128) // true + k.compareAndSet(128, 7777) // false - val kk: AtomicReference + val kk: AtomicReference kk = k } actual typealias KotlinAtomicReference = AtomicReference fun testTypealiasedKotlin() { - val k = KotlinAtomicReference(127) - k.compareAndSet(127, 128) // true - k.compareAndSet(128, 7777) // false + val k = KotlinAtomicReference(127) + k.compareAndSet(127, 128) // true + k.compareAndSet(128, 7777) // false - val kk: KotlinAtomicReference + val kk: KotlinAtomicReference kk = k } @@ -64,10 +64,10 @@ fun testTypealiasedKotlin() { import java.util.concurrent.atomic.AtomicReference fun testJava() { - val j = AtomicReference(127) - j.compareAndSet(127, 128) // true - j.compareAndSet(128, 7777) // false + val j = AtomicReference(127) + j.compareAndSet(127, 128) // true + j.compareAndSet(128, 7777) // false - val jj: AtomicReference + val jj: AtomicReference jj = j } diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/name/JvmStandardClassIds.kt b/core/compiler.common.jvm/src/org/jetbrains/kotlin/name/JvmStandardClassIds.kt index ff2c3e69e8bc3..9469127758e22 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/name/JvmStandardClassIds.kt +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/name/JvmStandardClassIds.kt @@ -165,6 +165,11 @@ object JvmStandardClassIds { object Callables { val JavaClass = CallableId(BASE_JVM_PACKAGE, Name.identifier("javaClass")) + + val atomicReferenceCompareAndSet = CallableId(ATOMIC_REFERENCE_CLASS_ID, Name.identifier("compareAndSet")) + val atomicReferenceCompareAndExchange = CallableId(ATOMIC_REFERENCE_CLASS_ID, Name.identifier("compareAndExchange")) + val atomicReferenceArrayCompareAndSet = CallableId(ATOMIC_REFERENCE_ARRAY_CLASS_ID, Name.identifier("compareAndSet")) + val atomicReferenceArrayCompareAndExchange = CallableId(ATOMIC_REFERENCE_ARRAY_CLASS_ID, Name.identifier("compareAndExchange")) } } diff --git a/core/compiler.common.native/src/org/jetbrains/kotlin/name/NativeRuntimeNames.kt b/core/compiler.common.native/src/org/jetbrains/kotlin/name/NativeRuntimeNames.kt index c67efcfc2c184..0e0839e28f267 100644 --- a/core/compiler.common.native/src/org/jetbrains/kotlin/name/NativeRuntimeNames.kt +++ b/core/compiler.common.native/src/org/jetbrains/kotlin/name/NativeRuntimeNames.kt @@ -31,6 +31,11 @@ object NativeRuntimeNames { object Callables { val AtomicArray = "AtomicArray".callableId(StandardClassIds.BASE_CONCURRENT_PACKAGE) + + val atomicReferenceCompareAndSet = "compareAndSet".callableId(AtomicReference) + val atomicReferenceCompareAndExchange = "compareAndExchange".callableId(AtomicReference) + val atomicArrayCompareAndSet = "compareAndSet".callableId(NativeRuntimeNames.AtomicArray) + val atomicArrayCompareAndExchange = "compareAndExchange".callableId(NativeRuntimeNames.AtomicArray) } object Annotations { @@ -56,3 +61,4 @@ object NativeRuntimeNames { } private fun String.callableId(packageName: FqName) = CallableId(packageName, Name.identifier(this)) +private fun String.callableId(classId: ClassId) = CallableId(classId, Name.identifier(this)) diff --git a/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt b/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt index 6e93e4452303e..79ad5b12ce6f5 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt @@ -275,6 +275,11 @@ object StandardClassIds { val not = "not".callableId(Boolean) val contract = "contract".callableId(BASE_CONTRACTS_PACKAGE) + + val atomicReferenceCompareAndSet = "compareAndSet".callableId(AtomicReference) + val atomicReferenceCompareAndExchange = "compareAndExchange".callableId(AtomicReference) + val atomicArrayCompareAndSetAt = "compareAndSetAt".callableId(AtomicArray) + val atomicArrayCompareAndExchangeAt = "compareAndExchangeAt".callableId(AtomicArray) } object Collections { diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/AtomicfuStandardClassIds.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/AtomicfuStandardClassIds.kt index 1bba68497f99d..07aeda4ceab3b 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/AtomicfuStandardClassIds.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/AtomicfuStandardClassIds.kt @@ -39,8 +39,12 @@ object AtomicfuStandardClassIds { object Callables { val atomic = "atomic".callableId(BASE_ATOMICFU_PACKAGE) + + val atomicRefCompareAndSet = "compareAndSet".callableId(AtomicRef) + val atomicRefCompareAndExchange = "compareAndExchange".callableId(AtomicRef) } } private fun String.atomicsId() = ClassId(AtomicfuStandardClassIds.BASE_ATOMICFU_PACKAGE, Name.identifier(this)) private fun String.callableId(packageName: FqName) = CallableId(packageName, Name.identifier(this)) +private fun String.callableId(classId: ClassId) = CallableId(classId, Name.identifier(this)) diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/diagnostic/AtomicfuAtomicRefToPrimitiveCallChecker.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/diagnostic/AtomicfuAtomicRefToPrimitiveCallChecker.kt index fafb8f3269977..70387d1eb960e 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/diagnostic/AtomicfuAtomicRefToPrimitiveCallChecker.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/diagnostic/AtomicfuAtomicRefToPrimitiveCallChecker.kt @@ -7,15 +7,11 @@ package org.jetbrains.kotlinx.atomicfu.compiler.diagnostic import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind import org.jetbrains.kotlin.fir.analysis.checkers.expression.AbstractAtomicReferenceToPrimitiveCallChecker -import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlinx.atomicfu.compiler.backend.AtomicfuStandardClassIds object AtomicfuAtomicRefToPrimitiveCallChecker : AbstractAtomicReferenceToPrimitiveCallChecker( - AtomicfuStandardClassIds.AtomicRef, AtomicfuStandardClassIds.atomicByPrimitive, MppCheckerKind.Platform, -) { - override val FirBasedSymbol<*>.canInstantiateProblematicAtomicReference: Boolean - get() = this is FirFunctionSymbol<*> && callableId == AtomicfuStandardClassIds.Callables.atomic -} + AtomicfuStandardClassIds.Callables.atomicRefCompareAndSet, + AtomicfuStandardClassIds.Callables.atomicRefCompareAndExchange, +) diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/diagnostic/AtomicfuAtomicRefToPrimitiveTypeChecker.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/diagnostic/AtomicfuAtomicRefToPrimitiveTypeChecker.kt deleted file mode 100644 index ba22cdfa43d94..0000000000000 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/diagnostic/AtomicfuAtomicRefToPrimitiveTypeChecker.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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. - */ - -package org.jetbrains.kotlinx.atomicfu.compiler.diagnostic - -import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind -import org.jetbrains.kotlin.fir.analysis.checkers.type.AbstractAtomicReferenceToPrimitiveTypeChecker -import org.jetbrains.kotlinx.atomicfu.compiler.backend.AtomicfuStandardClassIds - -object AtomicfuAtomicRefToPrimitiveTypeChecker : - AbstractAtomicReferenceToPrimitiveTypeChecker( - AtomicfuStandardClassIds.AtomicRef, - AtomicfuStandardClassIds.atomicByPrimitive, - MppCheckerKind.Platform, - ) - -object AtomicfuAtomicArrayToPrimitiveTypeChecker : - AbstractAtomicReferenceToPrimitiveTypeChecker( - AtomicfuStandardClassIds.AtomicArray, - AtomicfuStandardClassIds.atomicArrayByPrimitive, - MppCheckerKind.Platform, - ) diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/extensions/AtomicfuFirCheckers.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/extensions/AtomicfuFirCheckers.kt index fed2e9d2d2f18..a00e8756b7e52 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/extensions/AtomicfuFirCheckers.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/extensions/AtomicfuFirCheckers.kt @@ -22,14 +22,14 @@ class AtomicfuFirCheckers(session: FirSession) : FirAdditionalCheckersExtension( override val expressionCheckers: ExpressionCheckers = object : ExpressionCheckers() { override val functionCallCheckers: Set - get() = setOf(AtomicfuAtomicRefToPrimitiveCallChecker) + get() = setOf( + AtomicfuAtomicRefToPrimitiveCallChecker, + ) } override val typeCheckers: TypeCheckers = object : TypeCheckers() { override val resolvedTypeRefCheckers: Set get() = setOf( - AtomicfuAtomicRefToPrimitiveTypeChecker, - AtomicfuAtomicArrayToPrimitiveTypeChecker, ) } } diff --git a/plugins/atomicfu/atomicfu-compiler/testData/diagnostics/ErrorProneAtomicRefPrimitives.fir.diag.txt b/plugins/atomicfu/atomicfu-compiler/testData/diagnostics/ErrorProneAtomicRefPrimitives.fir.diag.txt index 4ea6060e2c5a5..b63da0f5a73fb 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/diagnostics/ErrorProneAtomicRefPrimitives.fir.diag.txt +++ b/plugins/atomicfu/atomicfu-compiler/testData/diagnostics/ErrorProneAtomicRefPrimitives.fir.diag.txt @@ -1,9 +1,5 @@ -/ErrorProneAtomicRefPrimitives.kt:(163,179): warning: 'AtomicRef' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicInt' instead. +/ErrorProneAtomicRefPrimitives.kt:(184,209): warning: This call may have inconsistent results because 'AtomicRef' uses identity equality and 'Int' does not have a consistent identity. Consider using 'AtomicInt' instead. -/ErrorProneAtomicRefPrimitives.kt:(271,285): warning: 'AtomicRef' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicInt' instead. +/ErrorProneAtomicRefPrimitives.kt:(222,248): warning: This call may have inconsistent results because 'AtomicRef' uses identity equality and 'Int' does not have a consistent identity. Consider using 'AtomicInt' instead. -/ErrorProneAtomicRefPrimitives.kt:(389,417): warning: 'AtomicRef' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicInt' instead. - -/ErrorProneAtomicRefPrimitives.kt:(427,443): warning: 'AtomicRef' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicInt' instead. - -/ErrorProneAtomicRefPrimitives.kt:(464,480): warning: 'AtomicArray' uses identity equality, but 'Int' does not have a consistent identity. Consider using 'AtomicIntArray' instead. +/ErrorProneAtomicRefPrimitives.kt:(448,474): warning: This call may have inconsistent results because 'AtomicRef' uses identity equality and 'Int' does not have a consistent identity. Consider using 'AtomicInt' instead. diff --git a/plugins/atomicfu/atomicfu-compiler/testData/diagnostics/ErrorProneAtomicRefPrimitives.kt b/plugins/atomicfu/atomicfu-compiler/testData/diagnostics/ErrorProneAtomicRefPrimitives.kt index 12f7f7d22f0fa..6f2ce6ef69ff9 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/diagnostics/ErrorProneAtomicRefPrimitives.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/diagnostics/ErrorProneAtomicRefPrimitives.kt @@ -7,19 +7,22 @@ import kotlinx.atomicfu.* fun test() { - val a = atomic(127) - a.compareAndSet(127, 128) // true - a.compareAndSet(128, 7777) // false + val a = atomic(127) + a.compareAndSet(127, 128) // true + a.compareAndSet(128, 7777) // false - val aa: AtomicRef + val aa: AtomicRef aa = a } typealias AtomicfuAtomicReference = AtomicRef fun testTypealiased() { - val aa: AtomicfuAtomicReference - aa = atomic(127) + val aa: AtomicfuAtomicReference + aa = atomic(127) + aa.compareAndSet(127, 128) } -fun testArray(a: AtomicArray) {} +fun testArray(a: AtomicArray) { + a[0].compareAndSet(1, 2) // A call on `AtomicRef` +}