Correct CFA order for enums: first own members, then entries, and at last companion object members #KT-6054 Fixed
(cherry picked from commit 94d3b4c)
This commit is contained in:
committed by
Mikhail Glukhikh
parent
1bc7b4e363
commit
13e64c18d9
@@ -1267,6 +1267,16 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClass(klass: KtClass) {
|
override fun visitClass(klass: KtClass) {
|
||||||
|
if (klass.hasPrimaryConstructor()) {
|
||||||
|
processParameters(klass.getPrimaryConstructorParameters())
|
||||||
|
|
||||||
|
// delegation specifiers of primary constructor, anonymous class and property initializers
|
||||||
|
generateHeaderDelegationSpecifiers(klass)
|
||||||
|
generateInitializersForScriptClassOrObject(klass)
|
||||||
|
}
|
||||||
|
|
||||||
|
generateDeclarationForLocalClassOrObjectIfNeeded(klass)
|
||||||
|
|
||||||
if (klass.isEnum()) {
|
if (klass.isEnum()) {
|
||||||
klass.declarations.forEach {
|
klass.declarations.forEach {
|
||||||
when (it) {
|
when (it) {
|
||||||
@@ -1279,21 +1289,12 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
generateInstructions(it)
|
generateInstructions(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is KtObjectDeclaration -> {
|
is KtObjectDeclaration -> if (it.isCompanion()) {
|
||||||
generateInstructions(it)
|
generateInstructions(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (klass.hasPrimaryConstructor()) {
|
|
||||||
processParameters(klass.getPrimaryConstructorParameters())
|
|
||||||
|
|
||||||
// delegation specifiers of primary constructor, anonymous class and property initializers
|
|
||||||
generateHeaderDelegationSpecifiers(klass)
|
|
||||||
generateInitializersForScriptClassOrObject(klass)
|
|
||||||
}
|
|
||||||
|
|
||||||
generateDeclarationForLocalClassOrObjectIfNeeded(klass)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitScript(script: KtScript) {
|
override fun visitScript(script: KtScript) {
|
||||||
|
|||||||
+8
-8
@@ -22,15 +22,15 @@ enum class E(val x: Int) {
|
|||||||
---------------------
|
---------------------
|
||||||
L0:
|
L0:
|
||||||
1 <START>
|
1 <START>
|
||||||
v(E1(0))
|
|
||||||
magic[FAKE_INITIALIZER](E1(0)) -> <v0>
|
|
||||||
w(E1|<v0>)
|
|
||||||
r(0) -> <v1>
|
|
||||||
mark((0))
|
|
||||||
call((0), <init>|<v1>) -> <v2>
|
|
||||||
v(val x: Int)
|
v(val x: Int)
|
||||||
magic[FAKE_INITIALIZER](val x: Int) -> <v3>
|
magic[FAKE_INITIALIZER](val x: Int) -> <v0>
|
||||||
w(x|<v3>)
|
w(x|<v0>)
|
||||||
|
v(E1(0))
|
||||||
|
magic[FAKE_INITIALIZER](E1(0)) -> <v1>
|
||||||
|
w(E1|<v1>)
|
||||||
|
r(0) -> <v2>
|
||||||
|
mark((0))
|
||||||
|
call((0), <init>|<v2>) -> <v3>
|
||||||
L1:
|
L1:
|
||||||
<END> NEXT:[<SINK>]
|
<END> NEXT:[<SINK>]
|
||||||
error:
|
error:
|
||||||
|
|||||||
+4
-4
@@ -10,10 +10,10 @@ enum class E(val x: Int) {
|
|||||||
E1(0)
|
E1(0)
|
||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
<v0>: E NEW: magic[FAKE_INITIALIZER](E1(0)) -> <v0>
|
<v0>: Int NEW: magic[FAKE_INITIALIZER](val x: Int) -> <v0>
|
||||||
<v3>: Int NEW: magic[FAKE_INITIALIZER](val x: Int) -> <v3>
|
<v1>: E NEW: magic[FAKE_INITIALIZER](E1(0)) -> <v1>
|
||||||
0 <v1>: Int NEW: r(0) -> <v1>
|
0 <v2>: Int NEW: r(0) -> <v2>
|
||||||
(0) <v2>: * NEW: call((0), <init>|<v1>) -> <v2>
|
(0) <v3>: * NEW: call((0), <init>|<v2>) -> <v3>
|
||||||
=====================
|
=====================
|
||||||
== C ==
|
== C ==
|
||||||
class C {
|
class C {
|
||||||
|
|||||||
+24
-2
@@ -29,7 +29,8 @@ enum class D(val x: Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class E(val v: Int) {
|
enum class E(val v: Int) {
|
||||||
E1(Nested.<!UNINITIALIZED_VARIABLE!>COPY<!>);
|
// KT-11769 related: there is no predictable initialization order for enum entry with non-companion object
|
||||||
|
E1(Nested.COPY);
|
||||||
|
|
||||||
object Nested {
|
object Nested {
|
||||||
val COPY = E1.v
|
val COPY = E1.v
|
||||||
@@ -41,4 +42,25 @@ object Object1 {
|
|||||||
object Object2 {
|
object Object2 {
|
||||||
val z: Any = Object1.y
|
val z: Any = Object1.y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From KT-11769
|
||||||
|
enum class Fruit(personal: Int) {
|
||||||
|
APPLE(1);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val common = 20
|
||||||
|
}
|
||||||
|
|
||||||
|
val score = personal + <!UNINITIALIZED_VARIABLE!>common<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
// From KT-6054
|
||||||
|
enum class MyEnum {
|
||||||
|
A, B;
|
||||||
|
val x = when(<!DEBUG_INFO_LEAKING_THIS!>this<!>) {
|
||||||
|
<!UNINITIALIZED_ENUM_ENTRY!>A<!> -> 1
|
||||||
|
<!UNINITIALIZED_ENUM_ENTRY!>B<!> -> 2
|
||||||
|
else -> 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+46
@@ -134,6 +134,52 @@ public final enum class E : kotlin.Enum<E> {
|
|||||||
public final /*synthesized*/ fun values(): kotlin.Array<E>
|
public final /*synthesized*/ fun values(): kotlin.Array<E>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final enum class Fruit : kotlin.Enum<Fruit> {
|
||||||
|
enum entry APPLE
|
||||||
|
|
||||||
|
private constructor Fruit(/*0*/ personal: kotlin.Int)
|
||||||
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
public final val score: kotlin.Int
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Fruit): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
public final val common: kotlin.Int = 20
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Fruit
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<Fruit>
|
||||||
|
}
|
||||||
|
|
||||||
|
public final enum class MyEnum : kotlin.Enum<MyEnum> {
|
||||||
|
enum entry A
|
||||||
|
|
||||||
|
enum entry B
|
||||||
|
|
||||||
|
private constructor MyEnum()
|
||||||
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
public final val x: kotlin.Int
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): MyEnum
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<MyEnum>
|
||||||
|
}
|
||||||
|
|
||||||
public object Object1 {
|
public object Object1 {
|
||||||
private constructor Object1()
|
private constructor Object1()
|
||||||
public final val y: kotlin.Any
|
public final val y: kotlin.Any
|
||||||
|
|||||||
Reference in New Issue
Block a user