[KLIB] Deserialize backing field initializers of const in IB-only mode
Missing const initializer leads to crash in property accessors inline lowering during IC recompilation on JS. - fix #KT-50512 - add test for JS IR IC
This commit is contained in:
+6
-6
@@ -456,11 +456,11 @@ class IrDeclarationDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun IrField.withInitializerGuard(f: IrField.() -> Unit) {
|
private fun IrField.withInitializerGuard(isConst: Boolean, f: IrField.() -> Unit) {
|
||||||
val oldBodiesPolicy = deserializeBodies
|
val oldBodiesPolicy = deserializeBodies
|
||||||
|
|
||||||
try {
|
try {
|
||||||
deserializeBodies = oldBodiesPolicy || type.checkObjectLeak()
|
deserializeBodies = isConst || oldBodiesPolicy || type.checkObjectLeak()
|
||||||
f()
|
f()
|
||||||
} finally {
|
} finally {
|
||||||
deserializeBodies = oldBodiesPolicy
|
deserializeBodies = oldBodiesPolicy
|
||||||
@@ -611,7 +611,7 @@ class IrDeclarationDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun deserializeIrField(proto: ProtoField): IrField =
|
private fun deserializeIrField(proto: ProtoField, isConst: Boolean): IrField =
|
||||||
withDeserializedIrDeclarationBase(proto.base) { symbol, uniqId, startOffset, endOffset, origin, fcode ->
|
withDeserializedIrDeclarationBase(proto.base) { symbol, uniqId, startOffset, endOffset, origin, fcode ->
|
||||||
checkSymbolType<IrFieldSymbol>(symbol)
|
checkSymbolType<IrFieldSymbol>(symbol)
|
||||||
val nameType = BinaryNameAndType.decode(proto.nameType)
|
val nameType = BinaryNameAndType.decode(proto.nameType)
|
||||||
@@ -633,7 +633,7 @@ class IrDeclarationDeserializer(
|
|||||||
|
|
||||||
field.usingParent {
|
field.usingParent {
|
||||||
if (proto.hasInitializer()) {
|
if (proto.hasInitializer()) {
|
||||||
withInitializerGuard {
|
withInitializerGuard(isConst) {
|
||||||
initializer = deserializeExpressionBody(proto.initializer)
|
initializer = deserializeExpressionBody(proto.initializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -699,7 +699,7 @@ class IrDeclarationDeserializer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (proto.hasBackingField()) {
|
if (proto.hasBackingField()) {
|
||||||
backingField = deserializeIrField(proto.backingField).also {
|
backingField = deserializeIrField(proto.backingField, prop.isConst).also {
|
||||||
it.correspondingPropertySymbol = symbol
|
it.correspondingPropertySymbol = symbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -722,7 +722,7 @@ class IrDeclarationDeserializer(
|
|||||||
val declaration: IrDeclaration = when (proto.declaratorCase!!) {
|
val declaration: IrDeclaration = when (proto.declaratorCase!!) {
|
||||||
IR_ANONYMOUS_INIT -> deserializeIrAnonymousInit(proto.irAnonymousInit)
|
IR_ANONYMOUS_INIT -> deserializeIrAnonymousInit(proto.irAnonymousInit)
|
||||||
IR_CONSTRUCTOR -> deserializeIrConstructor(proto.irConstructor)
|
IR_CONSTRUCTOR -> deserializeIrConstructor(proto.irConstructor)
|
||||||
IR_FIELD -> deserializeIrField(proto.irField)
|
IR_FIELD -> deserializeIrField(proto.irField, isConst = false)
|
||||||
IR_CLASS -> deserializeIrClass(proto.irClass)
|
IR_CLASS -> deserializeIrClass(proto.irClass)
|
||||||
IR_FUNCTION -> deserializeIrFunction(proto.irFunction)
|
IR_FUNCTION -> deserializeIrFunction(proto.irFunction)
|
||||||
IR_PROPERTY -> deserializeIrProperty(proto.irProperty)
|
IR_PROPERTY -> deserializeIrProperty(proto.irProperty)
|
||||||
|
|||||||
@@ -4150,6 +4150,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/incremental/classReferencingClass.kt");
|
runTest("js/js.translator/testData/box/incremental/classReferencingClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("constValInInlineFun.kt")
|
||||||
|
public void testConstValInInlineFun() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/incremental/constValInInlineFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("coroutines.kt")
|
@TestMetadata("coroutines.kt")
|
||||||
public void testCoroutines() throws Exception {
|
public void testCoroutines() throws Exception {
|
||||||
|
|||||||
+6
@@ -4522,6 +4522,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/incremental/classReferencingClass.kt");
|
runTest("js/js.translator/testData/box/incremental/classReferencingClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("constValInInlineFun.kt")
|
||||||
|
public void testConstValInInlineFun() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/incremental/constValInInlineFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("coroutines.kt")
|
@TestMetadata("coroutines.kt")
|
||||||
public void testCoroutines() throws Exception {
|
public void testCoroutines() throws Exception {
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// NO_COMMON_FILES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
const val FOO: String = "OK"
|
||||||
|
|
||||||
|
class B {
|
||||||
|
inline fun bar(): String {
|
||||||
|
return FOO // Constant property has to have a backing field with initializer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
// RECOMPILE
|
||||||
|
fun box(): String {
|
||||||
|
return B().bar()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user