[FIR] Don't miss non-const annotation args

This code with `b()` crashes the JVM
backend.

^KT-59822 Fixed
^KT-59874
This commit is contained in:
Nikolay Lunyak
2023-10-30 11:42:47 +02:00
committed by Space Team
parent 5a1a23afac
commit c656a83a02
13 changed files with 52 additions and 40 deletions
@@ -140,11 +140,6 @@ internal fun checkConstantArguments(
return ConstantArgumentKind.NOT_KCLASS_LITERAL return ConstantArgumentKind.NOT_KCLASS_LITERAL
} }
//TODO, KT-59822: UNRESOLVED REFERENCE
if (expression.dispatchReceiver is FirThisReceiverExpression) {
return null
}
if (calleeReference !is FirResolvedNamedReference) return ConstantArgumentKind.NOT_CONST if (calleeReference !is FirResolvedNamedReference) return ConstantArgumentKind.NOT_CONST
val symbol = calleeReference.resolvedSymbol as? FirNamedFunctionSymbol ?: return ConstantArgumentKind.NOT_CONST val symbol = calleeReference.resolvedSymbol as? FirNamedFunctionSymbol ?: return ConstantArgumentKind.NOT_CONST
@@ -183,11 +178,8 @@ internal fun checkConstantArguments(
val receiver = listOf(expression.dispatchReceiver, expression.extensionReceiver).single { it != null }!! val receiver = listOf(expression.dispatchReceiver, expression.extensionReceiver).single { it != null }!!
return checkConstantArguments(receiver, session) return checkConstantArguments(receiver, session)
} }
propertySymbol.isLocal || propertySymbol.callableId.className?.isRoot == false -> return ConstantArgumentKind.NOT_CONST propertySymbol.isLocal -> return ConstantArgumentKind.NOT_CONST
expressionType.fullyExpandedClassId(session) == StandardClassIds.KClass -> return ConstantArgumentKind.NOT_KCLASS_LITERAL expressionType.fullyExpandedClassId(session) == StandardClassIds.KClass -> return ConstantArgumentKind.NOT_KCLASS_LITERAL
//TODO, KT-59822: UNRESOLVED REFERENCE
expression.dispatchReceiver is FirThisReceiverExpression -> return null
} }
return when (property.initializer) { return when (property.initializer) {
is FirConstExpression<*> -> when { is FirConstExpression<*> -> when {
@@ -0,0 +1,5 @@
// Properties can be recursively annotated
annotation class ann(val x: Int)
class My {
@ann(<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>x<!>) val x: Int = 1
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// Properties can be recursively annotated // Properties can be recursively annotated
annotation class ann(val x: Int) annotation class ann(val x: Int)
class My { class My {
@@ -4,7 +4,7 @@ annotation class Anno(val number: Int)
fun topLevelFun() { fun topLevelFun() {
class LocalClass { class LocalClass {
@Anno(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>function(42)<!>) @Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>function(42)<!>)
fun function(@Anno(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>function(24)<!>) param: Int = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>function(0)<!>) = 1 fun function(@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>function(24)<!>) param: Int = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>function(0)<!>) = 1
} }
} }
@@ -6,6 +6,6 @@ annotation class Anno(val number: Int)
fun topLevelFun() { fun topLevelFun() {
class LocalClass { class LocalClass {
fun function(param: @Anno(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>function(42)<!>) Int) = 1 fun function(param: @Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>function(42)<!>) Int) = 1
} }
} }
@@ -1,15 +0,0 @@
package myPack
annotation class Anno(val number: String)
fun topLevelFun() {
class LocalClass {
@Anno(variableToResolve)
@field:Anno(variableToResolve)
var variableToResolve = "${42}"
@Anno(variableToResolve)
get() = field + "str"
@Anno(variableToResolve)
set(@Anno(variableToResolve) value) = Unit
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
package myPack package myPack
annotation class Anno(val number: String) annotation class Anno(val number: String)
@@ -4,11 +4,11 @@ annotation class Anno(val number: Int)
fun topLevel() { fun topLevel() {
class LocalClass { class LocalClass {
@Anno(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>prop<!>) @Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>prop<!>)
var prop var prop
@Anno(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>prop<!>) @Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>prop<!>)
get() = 22 get() = 22
@Anno(prop) @Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>prop<!>)
set(@Anno(prop) value) = Unit set(@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>prop<!>) value) = Unit
} }
} }
@@ -4,6 +4,6 @@ annotation class Anno(val number: Int)
fun topLevelFun() { fun topLevelFun() {
class LocalClass { class LocalClass {
fun @receiver:Anno(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>42.function()<!>) Int.function() = 1 fun @receiver:Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>42.function()<!>) Int.function() = 1
} }
} }
@@ -6,6 +6,6 @@ annotation class Anno(val number: Int)
fun topLevelFun() { fun topLevelFun() {
class LocalClass { class LocalClass {
fun <@Anno(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>function<String>()<!>) T> function() = 1 fun <@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>function<String>()<!>) T> function() = 1
} }
} }
@@ -23,8 +23,8 @@ class A
Companion.CONST, Companion.CONST,
Nested.CONST, Nested.CONST,
Interface.CONST, Interface.CONST,
<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>a<!>, <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>a<!>,
b() <!ANNOTATION_ARGUMENT_MUST_BE_CONST!>b()<!>
) )
constructor() { constructor() {
@@ -36,8 +36,8 @@ constructor() {
Companion.CONST, Companion.CONST,
Nested.CONST, Nested.CONST,
Interface.CONST, Interface.CONST,
<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>a<!>, <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>a<!>,
b() <!ANNOTATION_ARGUMENT_MUST_BE_CONST!>b()<!>
) )
constructor(dummy: Int) : this() constructor(dummy: Int) : this()
@@ -0,0 +1,31 @@
@Retention(AnnotationRetention.SOURCE)
@Repeatable
annotation class Ann(val i: Int)
annotation class AnnIA(val ia: IntArray)
annotation class AnnSA(val sa: Array<String>)
var i = 1
@Ann(<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>MyClass().i<!>)
@Ann(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>i<!>)
@Ann(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>i2<!>)
@AnnIA(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>ia<!>)
@AnnSA(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>sa<!>)
class Test {
val i = 1
@Ann(<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>i<!>) val i2 = 1
}
val i2 = foo()
fun foo(): Int = 1
@AnnSA(emptyArray())
class MyClass {
val i = 1
}
val ia: IntArray = intArrayOf(1, 2)
val sa: Array<String> = arrayOf("a", "b")
annotation class Ann2
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
@Repeatable @Repeatable
annotation class Ann(val i: Int) annotation class Ann(val i: Int)