[FIR] KT-54692: Fix compiler crash on UInt.shl
Merge-request: KT-MR-7513 Merged-by: Nikolay Lunyak <Nikolay.Lunyak@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
34478b84cd
commit
7e323f8ac6
@@ -277,7 +277,7 @@ private fun FirCallableSymbol<*>.toSymbolForCall(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun FirConstExpression<*>.getIrConstKind(): IrConstKind<*> = when (kind) {
|
fun FirConstExpression<*>.getIrConstKind(): IrConstKind<*> = when (kind) {
|
||||||
ConstantValueKind.IntegerLiteral -> {
|
ConstantValueKind.IntegerLiteral, ConstantValueKind.UnsignedIntegerLiteral -> {
|
||||||
val type = typeRef.coneTypeUnsafe<ConeIntegerLiteralType>()
|
val type = typeRef.coneTypeUnsafe<ConeIntegerLiteralType>()
|
||||||
type.getApproximatedType().toConstKind()!!.toIrConstKind()
|
type.getApproximatedType().toConstKind()!!.toIrConstKind()
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -41154,6 +41154,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("bitShifting.kt")
|
||||||
|
public void testBitShifting() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/ranges/unsigned/bitShifting.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("inMixedUnsignedRange.kt")
|
@TestMetadata("inMixedUnsignedRange.kt")
|
||||||
public void testInMixedUnsignedRange() throws Exception {
|
public void testInMixedUnsignedRange() throws Exception {
|
||||||
|
|||||||
+4
@@ -19,5 +19,9 @@ object ConvertibleIntegerOperators {
|
|||||||
"inv", "unaryPlus", "unaryMinus"
|
"inv", "unaryPlus", "unaryMinus"
|
||||||
).toNameSet()
|
).toNameSet()
|
||||||
|
|
||||||
|
val binaryOperatorsWithSignedArgument: Set<Name> = listOf(
|
||||||
|
"shl", "shr", "ushr",
|
||||||
|
).toNameSet()
|
||||||
|
|
||||||
private fun List<String>.toNameSet(): Set<Name> = mapTo(mutableSetOf()) { Name.identifier(it) }
|
private fun List<String>.toNameSet(): Set<Name> = mapTo(mutableSetOf()) { Name.identifier(it) }
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
|||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
import org.jetbrains.kotlin.fir.scopes.getFunctions
|
import org.jetbrains.kotlin.fir.scopes.getFunctions
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.ConvertibleIntegerOperators.binaryOperatorsWithSignedArgument
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
@@ -46,6 +47,7 @@ class FirIntegerConstantOperatorScope(
|
|||||||
if (!isUnaryOperator && !isBinaryOperator) {
|
if (!isUnaryOperator && !isBinaryOperator) {
|
||||||
return baseScope.processFunctionsByName(name, processor)
|
return baseScope.processFunctionsByName(name, processor)
|
||||||
}
|
}
|
||||||
|
val requiresUnsignedOperand = isUnsigned && name !in binaryOperatorsWithSignedArgument
|
||||||
val wrappedSymbol = mappedFunctions.getOrPut(name) {
|
val wrappedSymbol = mappedFunctions.getOrPut(name) {
|
||||||
val allFunctions = baseScope.getFunctions(name)
|
val allFunctions = baseScope.getFunctions(name)
|
||||||
val functionSymbol = allFunctions.first {
|
val functionSymbol = allFunctions.first {
|
||||||
@@ -53,7 +55,7 @@ class FirIntegerConstantOperatorScope(
|
|||||||
if (isUnaryOperator) return@first true
|
if (isUnaryOperator) return@first true
|
||||||
|
|
||||||
val coneType = it.fir.valueParameters.first().returnTypeRef.coneType
|
val coneType = it.fir.valueParameters.first().returnTypeRef.coneType
|
||||||
if (isUnsigned) {
|
if (requiresUnsignedOperand) {
|
||||||
coneType.isUInt
|
coneType.isUInt
|
||||||
} else {
|
} else {
|
||||||
coneType.isInt
|
coneType.isInt
|
||||||
|
|||||||
@@ -566,7 +566,11 @@ fun FirExpression?.isIntegerLiteralOrOperatorCall(): Boolean {
|
|||||||
returns(true) implies (this@isIntegerLiteralOrOperatorCall != null)
|
returns(true) implies (this@isIntegerLiteralOrOperatorCall != null)
|
||||||
}
|
}
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is FirConstExpression<*> -> kind == ConstantValueKind.Int || kind == ConstantValueKind.IntegerLiteral
|
is FirConstExpression<*> -> kind == ConstantValueKind.Int
|
||||||
|
|| kind == ConstantValueKind.IntegerLiteral
|
||||||
|
|| kind == ConstantValueKind.UnsignedInt
|
||||||
|
|| kind == ConstantValueKind.UnsignedIntegerLiteral
|
||||||
|
|
||||||
is FirIntegerLiteralOperatorCall -> true
|
is FirIntegerLiteralOperatorCall -> true
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirArrayOfCall
|
|||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.remapArgumentsWithVararg
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.remapArgumentsWithVararg
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.writeResultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.writeResultType
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.ConvertibleIntegerOperators.binaryOperatorsWithSignedArgument
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperator
|
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperator
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperatorForUnsignedType
|
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperatorForUnsignedType
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
@@ -469,7 +470,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
val arguments = argumentMapping?.map { (argument, valueParameter) ->
|
val arguments = argumentMapping?.map { (argument, valueParameter) ->
|
||||||
val expectedType = when {
|
val expectedType = when {
|
||||||
isIntegerOperator -> ConeIntegerConstantOperatorTypeImpl(
|
isIntegerOperator -> ConeIntegerConstantOperatorTypeImpl(
|
||||||
isUnsigned = symbol.isWrappedIntegerOperatorForUnsignedType(),
|
isUnsigned = symbol.isWrappedIntegerOperatorForUnsignedType() && callInfo.name in binaryOperatorsWithSignedArgument,
|
||||||
ConeNullability.NOT_NULL
|
ConeNullability.NOT_NULL
|
||||||
)
|
)
|
||||||
valueParameter.isVararg -> valueParameter.returnTypeRef.substitute(this).varargElementType()
|
valueParameter.isVararg -> valueParameter.returnTypeRef.substitute(this).varargElementType()
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// WITH_STDLIB
|
||||||
|
|
||||||
|
fun test(): Int {
|
||||||
|
return 1 shl 12
|
||||||
|
}
|
||||||
|
|
||||||
|
fun rest(): UInt {
|
||||||
|
return 1u shl 20
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fest(): Long {
|
||||||
|
return 1L shl 12
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mest(): ULong {
|
||||||
|
return 1uL shl 20
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String = when {
|
||||||
|
test() != 4096 -> "fail: test"
|
||||||
|
rest() != 1_048_576u -> "fail: rest"
|
||||||
|
fest() != 4096L -> "fail: fest"
|
||||||
|
mest() != 1_048_576uL -> "fail: mest"
|
||||||
|
else -> "OK"
|
||||||
|
}
|
||||||
+6
@@ -39678,6 +39678,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("bitShifting.kt")
|
||||||
|
public void testBitShifting() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/ranges/unsigned/bitShifting.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("inMixedUnsignedRange.kt")
|
@TestMetadata("inMixedUnsignedRange.kt")
|
||||||
public void testInMixedUnsignedRange() throws Exception {
|
public void testInMixedUnsignedRange() throws Exception {
|
||||||
|
|||||||
+6
@@ -41154,6 +41154,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("bitShifting.kt")
|
||||||
|
public void testBitShifting() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/ranges/unsigned/bitShifting.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("inMixedUnsignedRange.kt")
|
@TestMetadata("inMixedUnsignedRange.kt")
|
||||||
public void testInMixedUnsignedRange() throws Exception {
|
public void testInMixedUnsignedRange() throws Exception {
|
||||||
|
|||||||
+5
@@ -31595,6 +31595,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("bitShifting.kt")
|
||||||
|
public void testBitShifting() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/ranges/unsigned/bitShifting.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("inMixedUnsignedRange.kt")
|
@TestMetadata("inMixedUnsignedRange.kt")
|
||||||
public void testInMixedUnsignedRange() throws Exception {
|
public void testInMixedUnsignedRange() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/ranges/unsigned/inMixedUnsignedRange.kt");
|
runTest("compiler/testData/codegen/box/ranges/unsigned/inMixedUnsignedRange.kt");
|
||||||
|
|||||||
+6
@@ -30752,6 +30752,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("bitShifting.kt")
|
||||||
|
public void testBitShifting() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/ranges/unsigned/bitShifting.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("inMixedUnsignedRange.kt")
|
@TestMetadata("inMixedUnsignedRange.kt")
|
||||||
public void testInMixedUnsignedRange() throws Exception {
|
public void testInMixedUnsignedRange() throws Exception {
|
||||||
|
|||||||
+6
@@ -30932,6 +30932,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("bitShifting.kt")
|
||||||
|
public void testBitShifting() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/ranges/unsigned/bitShifting.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("inMixedUnsignedRange.kt")
|
@TestMetadata("inMixedUnsignedRange.kt")
|
||||||
public void testInMixedUnsignedRange() throws Exception {
|
public void testInMixedUnsignedRange() throws Exception {
|
||||||
|
|||||||
+5
@@ -27640,6 +27640,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("bitShifting.kt")
|
||||||
|
public void testBitShifting() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/ranges/unsigned/bitShifting.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("inMixedUnsignedRange.kt")
|
@TestMetadata("inMixedUnsignedRange.kt")
|
||||||
public void testInMixedUnsignedRange() throws Exception {
|
public void testInMixedUnsignedRange() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/ranges/unsigned/inMixedUnsignedRange.kt");
|
runTest("compiler/testData/codegen/box/ranges/unsigned/inMixedUnsignedRange.kt");
|
||||||
|
|||||||
+6
@@ -33911,6 +33911,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges/unsigned"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("bitShifting.kt")
|
||||||
|
public void testBitShifting() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/ranges/unsigned/bitShifting.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("inMixedUnsignedRange.kt")
|
@TestMetadata("inMixedUnsignedRange.kt")
|
||||||
public void testInMixedUnsignedRange() throws Exception {
|
public void testInMixedUnsignedRange() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user