[FIR2IR] Remove incorrect usages of Fir2IrDeclarationStorage.getOrCreateIrFunction

`getOrCreateXxx` methods have not very safe semantics: they sometimes
  create an IR declaration if it was missing in caches before. For all
  source declarations, this is not very good semantic, because we have
  strict rules in which order source declarations should be created,
  and usage of `getOrCreateXxx` may break this order.
So it's important to be able to track all invocations of such methods
  to ensure that it's appropriate in each case.
To achieve that, a new `@GetOrCreateSensitiveAPI ` opt-in is introduced
This commit is contained in:
Dmitriy Novozhilov
2023-10-24 15:00:01 +03:00
committed by Space Team
parent af6b71ca2d
commit bced604b57
9 changed files with 23 additions and 5 deletions
@@ -458,6 +458,9 @@ class Fir2IrConverter(
}
}
/**
* This function creates IR declarations for callable members without filling their body
*/
private fun processMemberDeclaration(
declaration: FirDeclaration,
containingClass: FirClass?,
@@ -508,7 +511,7 @@ class Fir2IrConverter(
}
}
is FirSimpleFunction -> {
declarationStorage.getOrCreateIrFunction(declaration, parent, isLocal = isInLocalClass)
declarationStorage.createAndCacheIrFunction(declaration, parent, isLocal = isInLocalClass)
}
is FirProperty -> {
if (
@@ -269,6 +269,7 @@ class Fir2IrDeclarationStorage(
return cachedIrCallable
}
@GetOrCreateSensitiveAPI
fun getOrCreateIrFunction(
function: FirFunction,
irParent: IrDeclarationParent?,
@@ -279,6 +280,7 @@ class Fir2IrDeclarationStorage(
return getOrCreateIrFunction(function, { irParent }, predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag)
}
@GetOrCreateSensitiveAPI
private fun getOrCreateIrFunction(
function: FirFunction,
irParent: () -> IrDeclarationParent?,
@@ -301,7 +303,6 @@ class Fir2IrDeclarationStorage(
return createAndCacheIrFunction(function, irParent(), predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag)
}
@LeakedDeclarationCaches
fun createAndCacheIrFunction(
function: FirFunction,
irParent: IrDeclarationParent?,
@@ -874,6 +875,7 @@ class Fir2IrDeclarationStorage(
getIrConstructorSymbol(fir.symbol)
}
else -> {
@OptIn(GetOrCreateSensitiveAPI::class)
getOrCreateIrFunction(
fir,
{ findIrParent(fir, fakeOverrideOwnerLookupTag) },
@@ -1177,6 +1179,13 @@ internal var FirProperty.isStubPropertyForPureField: Boolean? by FirDeclarationD
@RequiresOptIn
annotation class LeakedDeclarationCaches
/**
* This annotation indicates that an annotated method can create a declaration in ad-hock way, so it should be used with caution
* In most cases, it's recommended to use method which return symbol or which forcefully creates a declaration
*/
@RequiresOptIn
annotation class GetOrCreateSensitiveAPI
@OptIn(UnsafeDuringIrConstructionAPI::class)
internal fun <D : IrDeclaration> IrBindableSymbol<*, D>.ownerIfBound(): D? {
return runIf(isBound) { owner }
@@ -401,7 +401,7 @@ class Fir2IrVisitor(
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): IrElement = whileAnalysing(session, simpleFunction) {
val irFunction = if (simpleFunction.visibility == Visibilities.Local) {
declarationStorage.getOrCreateIrFunction(
declarationStorage.createAndCacheIrFunction(
simpleFunction, irParent = conversionScope.parent(), predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION, isLocal = true
)
} else {
@@ -424,7 +424,7 @@ class Fir2IrVisitor(
data: Any?
): IrElement = whileAnalysing(session, anonymousFunction) {
return anonymousFunction.convertWithOffsets { startOffset, endOffset ->
val irFunction = declarationStorage.getOrCreateIrFunction(
val irFunction = declarationStorage.createAndCacheIrFunction(
anonymousFunction,
irParent = conversionScope.parent(),
predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION,
@@ -173,6 +173,7 @@ class FirIrProvider(val components: Fir2IrComponents) : IrProvider {
}
SymbolKind.FUNCTION_SYMBOL -> {
val firSimpleFunction = firDeclaration as FirSimpleFunction
@OptIn(GetOrCreateSensitiveAPI::class)
declarationStorage.getOrCreateIrFunction(firSimpleFunction, parent)
}
SymbolKind.PROPERTY_SYMBOL -> {
@@ -698,6 +698,7 @@ class IrBuiltInsOverFir(
functionSymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
val irParent = findIrParent(functionSymbol)
@OptIn(GetOrCreateSensitiveAPI::class)
return components.declarationStorage.getOrCreateIrFunction(functionSymbol.fir, irParent).symbol
}
@@ -214,7 +214,7 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
firSubClass: FirClass,
delegateOverride: FirSimpleFunction
): IrSimpleFunction {
val delegateFunction = declarationStorage.getOrCreateIrFunction(
val delegateFunction = declarationStorage.createAndCacheIrFunction(
delegateOverride, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER,
fakeOverrideOwnerLookupTag = firSubClass.symbol.toLookupTag()
)
@@ -195,6 +195,7 @@ class Fir2IrLazyClass(
symbol.containingClassLookupTag() != ownerLookupTag -> {}
symbol.isAbstractMethodOfAny() -> {}
else -> {
@OptIn(GetOrCreateSensitiveAPI::class)
result += declarationStorage.getOrCreateIrFunction(symbol.fir, this, origin)
}
}
@@ -125,6 +125,7 @@ class Fir2IrLazyPropertyAccessor(
override val initialSignatureFunction: IrFunction? by lazy {
val originalFirFunction = (fir as? FirSyntheticPropertyAccessor)?.delegate ?: return@lazy null
@OptIn(GetOrCreateSensitiveAPI::class)
declarationStorage.getOrCreateIrFunction(originalFirFunction, parent)
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.lazy
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.GetOrCreateSensitiveAPI
import org.jetbrains.kotlin.fir.backend.contextReceiversForFunctionOrContainingProperty
import org.jetbrains.kotlin.fir.backend.generators.Fir2IrCallableDeclarationsGenerator
import org.jetbrains.kotlin.fir.backend.generators.generateOverriddenFunctionSymbols
@@ -110,6 +111,7 @@ class Fir2IrLazySimpleFunction(
override val initialSignatureFunction: IrFunction? by lazy {
val originalFunction = fir.initialSignatureAttr as? FirFunction ?: return@lazy null
@OptIn(GetOrCreateSensitiveAPI::class)
declarationStorage.getOrCreateIrFunction(originalFunction, parent).also {
check(it !== this) { "Initial function can not be the same as remapped function" }
}