[JVM_IR] Fix accessibility bridges for static protected fields.

Super-qualifiers have to be taken into account. Otherwise, too
few accessibility bridges will be generated which can lead to
binary compatibility issues.
This commit is contained in:
Mads Ager
2021-01-21 16:19:59 +01:00
committed by Alexander Udalov
parent 62897a194b
commit 6a959fefd0
6 changed files with 155 additions and 19 deletions
@@ -68,9 +68,11 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
}
}
private data class FieldKey(val fieldSymbol: IrFieldSymbol, val parent: IrDeclarationParent, val superQualifierSymbol: IrClassSymbol?)
private val functionMap = mutableMapOf<Pair<IrFunctionSymbol, IrDeclarationParent>, IrFunctionSymbol>()
private val getterMap = mutableMapOf<Pair<IrFieldSymbol, IrDeclarationParent>, IrSimpleFunctionSymbol>()
private val setterMap = mutableMapOf<Pair<IrFieldSymbol, IrDeclarationParent>, IrSimpleFunctionSymbol>()
private val getterMap = mutableMapOf<FieldKey, IrSimpleFunctionSymbol>()
private val setterMap = mutableMapOf<FieldKey, IrSimpleFunctionSymbol>()
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression {
if (expression.usesDefaultArguments()) {
@@ -158,7 +160,9 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
symbol.owner.accessorParent(dispatchReceiverType?.classOrNull?.owner ?: symbol.owner.parent) as IrClass
modifyGetterExpression(
expression,
getterMap.getOrPut(Pair(symbol, parent)) { makeGetterAccessorSymbol(symbol, parent) }
getterMap.getOrPut(FieldKey(symbol, parent, expression.superQualifierSymbol)) {
makeGetterAccessorSymbol(symbol, parent, expression.superQualifierSymbol)
}
)
} else {
expression
@@ -175,7 +179,9 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
symbol.owner.accessorParent(dispatchReceiverType?.classOrNull?.owner ?: symbol.owner.parent) as IrClass
modifySetterExpression(
expression,
setterMap.getOrPut(Pair(symbol, parent)) { makeSetterAccessorSymbol(symbol, parent) }
setterMap.getOrPut(FieldKey(symbol, parent, expression.superQualifierSymbol)) {
makeSetterAccessorSymbol(symbol, parent, expression.superQualifierSymbol)
}
)
} else {
expression
@@ -348,12 +354,16 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
copyAllParamsToArgs(it, accessor)
}
private fun makeGetterAccessorSymbol(fieldSymbol: IrFieldSymbol, parent: IrClass): IrSimpleFunctionSymbol =
private fun makeGetterAccessorSymbol(
fieldSymbol: IrFieldSymbol,
parent: IrClass,
superQualifierSymbol: IrClassSymbol?
): IrSimpleFunctionSymbol =
context.irFactory.buildFun {
startOffset = parent.startOffset
endOffset = parent.startOffset
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
name = fieldSymbol.owner.accessorNameForGetter()
name = fieldSymbol.owner.accessorNameForGetter(superQualifierSymbol)
visibility = DescriptorVisibilities.PUBLIC
modality = Modality.FINAL
returnType = fieldSymbol.owner.type
@@ -368,10 +378,14 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
)
}
accessor.body = createAccessorBodyForGetter(fieldSymbol.owner, accessor)
accessor.body = createAccessorBodyForGetter(fieldSymbol.owner, accessor, superQualifierSymbol)
}.symbol
private fun createAccessorBodyForGetter(targetField: IrField, accessor: IrSimpleFunction): IrBody {
private fun createAccessorBodyForGetter(
targetField: IrField,
accessor: IrSimpleFunction,
superQualifierSymbol: IrClassSymbol?
): IrBody {
val maybeDispatchReceiver =
if (targetField.isStatic) null
else IrGetValueImpl(accessor.startOffset, accessor.endOffset, accessor.valueParameters[0].symbol)
@@ -381,17 +395,22 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
accessor.startOffset, accessor.endOffset,
targetField.symbol,
targetField.type,
maybeDispatchReceiver
maybeDispatchReceiver,
superQualifierSymbol = superQualifierSymbol
)
)
}
private fun makeSetterAccessorSymbol(fieldSymbol: IrFieldSymbol, parent: IrClass): IrSimpleFunctionSymbol =
private fun makeSetterAccessorSymbol(
fieldSymbol: IrFieldSymbol,
parent: IrClass,
superQualifierSymbol: IrClassSymbol?
): IrSimpleFunctionSymbol =
context.irFactory.buildFun {
startOffset = parent.startOffset
endOffset = parent.startOffset
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
name = fieldSymbol.owner.accessorNameForSetter()
name = fieldSymbol.owner.accessorNameForSetter(superQualifierSymbol)
visibility = DescriptorVisibilities.PUBLIC
modality = Modality.FINAL
returnType = context.irBuiltIns.unitType
@@ -408,10 +427,14 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
accessor.addValueParameter("<set-?>", fieldSymbol.owner.type, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR)
accessor.body = createAccessorBodyForSetter(fieldSymbol.owner, accessor)
accessor.body = createAccessorBodyForSetter(fieldSymbol.owner, accessor, superQualifierSymbol)
}.symbol
private fun createAccessorBodyForSetter(targetField: IrField, accessor: IrSimpleFunction): IrBody {
private fun createAccessorBodyForSetter(
targetField: IrField,
accessor: IrSimpleFunction,
superQualifierSymbol: IrClassSymbol?
): IrBody {
val maybeDispatchReceiver =
if (targetField.isStatic) null
else IrGetValueImpl(accessor.startOffset, accessor.endOffset, accessor.valueParameters[0].symbol)
@@ -426,7 +449,8 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
targetField.symbol,
maybeDispatchReceiver,
value,
context.irBuiltIns.unitType
context.irBuiltIns.unitType,
superQualifierSymbol = superQualifierSymbol
)
)
}
@@ -565,22 +589,26 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
return Name.identifier("access\$$jvmName$suffix")
}
private fun IrField.accessorNameForGetter(): Name {
private fun IrField.accessorNameForGetter(superQualifierSymbol: IrClassSymbol?): Name {
val getterName = JvmAbi.getterName(name.asString())
return Name.identifier("access\$$getterName\$${fieldAccessorSuffix()}")
return Name.identifier("access\$$getterName\$${fieldAccessorSuffix(superQualifierSymbol)}")
}
private fun IrField.accessorNameForSetter(): Name {
private fun IrField.accessorNameForSetter(superQualifierSymbol: IrClassSymbol?): Name {
val setterName = JvmAbi.setterName(name.asString())
return Name.identifier("access\$$setterName\$${fieldAccessorSuffix()}")
return Name.identifier("access\$$setterName\$${fieldAccessorSuffix(superQualifierSymbol)}")
}
private fun IrField.fieldAccessorSuffix(): String {
private fun IrField.fieldAccessorSuffix(superQualifierSymbol: IrClassSymbol?): String {
// Special _c_ompanion _p_roperty suffix for accessing companion backing field moved to outer
if (origin == JvmLoweredDeclarationOrigin.COMPANION_PROPERTY_BACKING_FIELD && !parentAsClass.isCompanion) {
return "cp"
}
if (superQualifierSymbol != null) {
return "p\$s${superQualifierSymbol.owner.syntheticAccessorToSuperSuffix()}"
}
// Accesses to static protected fields that need an accessor must be due to being inherited, hence accessed on a
// _s_upertype. If the field is static, the super class the access is on can be different and therefore
// we generate a suffix to distinguish access to field with different receiver types in the super hierarchy.