[FIR] fix publication race in fakeOverrideSubstitution

Problem: fakeOverrideSubstitution was set to null before the return
type was published, so another thread can see a state where
fakeOverrideSubstitution is null and a return type is implicit
simultaneously

^KT-60385
^KT-59758 Fixed
This commit is contained in:
Dmitrii Gridin
2023-07-12 14:27:33 +02:00
committed by Space Team
parent 17da09bf17
commit 97a12af03e
2 changed files with 14 additions and 5 deletions
@@ -26,19 +26,21 @@ abstract class FakeOverrideTypeCalculator {
abstract class AbstractFakeOverrideTypeCalculator : FakeOverrideTypeCalculator() {
override fun computeReturnType(declaration: FirCallableDeclaration): FirResolvedTypeRef? {
val fakeOverrideSubstitution = declaration.attributes.fakeOverrideSubstitution
?: return declaration.getResolvedTypeRef()
val fakeOverrideSubstitution = declaration.attributes.fakeOverrideSubstitution ?: return declaration.getResolvedTypeRef()
// TODO: drop synchronized in KT-60385
synchronized(fakeOverrideSubstitution) {
if (declaration.attributes.fakeOverrideSubstitution == null) {
return declaration.returnTypeRef as FirResolvedTypeRef
}
val (substitutor, baseSymbol) = fakeOverrideSubstitution
val baseDeclaration = baseSymbol.fir as FirCallableDeclaration
val baseReturnType = computeReturnType(baseDeclaration)?.type ?: return null
declaration.attributes.fakeOverrideSubstitution = null
val coneType = substitutor.substituteOrSelf(baseReturnType)
val returnType = declaration.returnTypeRef.resolvedTypeFromPrototype(coneType)
declaration.replaceReturnTypeRef(returnType)
declaration.attributes.fakeOverrideSubstitution = null
return returnType
}
}
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.visitors.FirTransformer
@@ -231,9 +232,13 @@ open class ReturnTypeCalculatorWithJump(
if (declaration.isSubstitutionOrIntersectionOverride) {
val fakeOverrideSubstitution = declaration.attributes.fakeOverrideSubstitution
?: return declaration.returnTypeRef as FirResolvedTypeRef
// TODO: drop synchronized in KT-60385
synchronized(fakeOverrideSubstitution) {
(declaration.returnTypeRef as? FirResolvedTypeRef)?.let { return it }
declaration.attributes.fakeOverrideSubstitution = null
if (declaration.attributes.fakeOverrideSubstitution == null) {
return declaration.returnTypeRef as FirResolvedTypeRef
}
val (substitutor, baseSymbol) = fakeOverrideSubstitution
val baseDeclaration = baseSymbol.fir as FirCallableDeclaration
val baseReturnTypeRef = tryCalculateReturnType(baseDeclaration)
@@ -245,6 +250,8 @@ open class ReturnTypeCalculatorWithJump(
declaration.getter?.replaceReturnTypeRef(returnType)
declaration.setter?.valueParameters?.firstOrNull()?.replaceReturnTypeRef(returnType)
}
declaration.attributes.fakeOverrideSubstitution = null
return returnType
}
}