Check for accessibility of unsigned types when using unsigned literals

This commit is contained in:
Mikhail Zarechenskiy
2018-08-27 13:21:12 +03:00
parent afd53c9870
commit 3f79a752a5
5 changed files with 33 additions and 6 deletions
@@ -303,7 +303,6 @@ class ConstantExpressionEvaluator(
if (!UnsignedTypes.isUnsignedType(constantType)) return if (!UnsignedTypes.isUnsignedType(constantType)) return
with(ExperimentalUsageChecker) { with(ExperimentalUsageChecker) {
val descriptor = constantType.constructor.declarationDescriptor ?: return val descriptor = constantType.constructor.declarationDescriptor ?: return
val experimentalities = descriptor.loadExperimentalities(moduleAnnotationsResolver, languageVersionSettings) val experimentalities = descriptor.loadExperimentalities(moduleAnnotationsResolver, languageVersionSettings)
@@ -986,6 +985,15 @@ private class ConstantExpressionEvaluatorVisitor(
parameters: CompileTimeConstant.Parameters, parameters: CompileTimeConstant.Parameters,
expectedType: KotlinType expectedType: KotlinType
): CompileTimeConstant<*>? { ): CompileTimeConstant<*>? {
if (parameters.isUnsignedNumberLiteral &&
!checkAccessibilityOfUnsignedTypes(
constantExpressionEvaluator.module,
constantExpressionEvaluator.languageVersionSettings
)
) {
return UnsignedErrorValueTypeConstant(value, parameters)
}
if (parameters.isUnsignedLongNumberLiteral) { if (parameters.isUnsignedLongNumberLiteral) {
return ULongValue(value).wrap(parameters) return ULongValue(value).wrap(parameters)
} }
@@ -1013,6 +1021,13 @@ private class ConstantExpressionEvaluatorVisitor(
}.wrap(parameters) }.wrap(parameters)
} }
private fun checkAccessibilityOfUnsignedTypes(module: ModuleDescriptor, languageVersionSettings: LanguageVersionSettings): Boolean {
val uInt = module.findClassAcrossModuleDependencies(KotlinBuiltIns.FQ_NAMES.uInt) ?: return false
val accessibility = uInt.checkSinceKotlinVersionAccessibility(languageVersionSettings)
// Case `NotAccessibleButWasExperimental` will be checked later in `checkExperimentalityOfConstantLiteral`
return accessibility is SinceKotlinAccessibility.Accessible
}
private fun <T> ConstantValue<T>.wrap(parameters: CompileTimeConstant.Parameters): TypedCompileTimeConstant<T> = private fun <T> ConstantValue<T>.wrap(parameters: CompileTimeConstant.Parameters): TypedCompileTimeConstant<T> =
TypedCompileTimeConstant(this, constantExpressionEvaluator.module, parameters) TypedCompileTimeConstant(this, constantExpressionEvaluator.module, parameters)
@@ -0,0 +1,6 @@
// !API_VERSION: 1.2
val a = <!UNSIGNED_LITERAL_WITHOUT_DECLARATIONS_ON_CLASSPATH!>0u<!>
val b = <!UNSIGNED_LITERAL_WITHOUT_DECLARATIONS_ON_CLASSPATH!>1uL<!>
fun foo(<!UNUSED_PARAMETER!>u<!>: <!UNRESOLVED_REFERENCE!>UInt<!>) {}
@@ -0,0 +1,5 @@
package
public val a: [ERROR : Type cannot be resolved. Please make sure you have the required dependencies for unsigned types in the classpath]
public val b: [ERROR : Type cannot be resolved. Please make sure you have the required dependencies for unsigned types in the classpath]
public fun foo(/*0*/ u: [ERROR : UInt]): kotlin.Unit
@@ -64,6 +64,11 @@ public class DiagnosticsWithUnsignedTypesGenerated extends AbstractDiagnosticsWi
runTest("compiler/testData/diagnostics/testsWithUnsignedTypes/unsignedLiteralsInsideConstVals.kt"); runTest("compiler/testData/diagnostics/testsWithUnsignedTypes/unsignedLiteralsInsideConstVals.kt");
} }
@TestMetadata("unsignedLiteralsOn1_2.kt")
public void testUnsignedLiteralsOn1_2() throws Exception {
runTest("compiler/testData/diagnostics/testsWithUnsignedTypes/unsignedLiteralsOn1_2.kt");
}
@TestMetadata("unsignedLiteralsOverflowSignedBorder.kt") @TestMetadata("unsignedLiteralsOverflowSignedBorder.kt")
public void testUnsignedLiteralsOverflowSignedBorder() throws Exception { public void testUnsignedLiteralsOverflowSignedBorder() throws Exception {
runTest("compiler/testData/diagnostics/testsWithUnsignedTypes/unsignedLiteralsOverflowSignedBorder.kt"); runTest("compiler/testData/diagnostics/testsWithUnsignedTypes/unsignedLiteralsOverflowSignedBorder.kt");
@@ -93,11 +93,7 @@ fun createIntegerValueTypeConstant(
module: ModuleDescriptor, module: ModuleDescriptor,
parameters: CompileTimeConstant.Parameters parameters: CompileTimeConstant.Parameters
): CompileTimeConstant<*> { ): CompileTimeConstant<*> {
return if (parameters.isUnsignedNumberLiteral && !hasUnsignedTypesInModuleDependencies(module)) { return IntegerValueTypeConstant(value, module, parameters)
UnsignedErrorValueTypeConstant(value, parameters)
} else {
IntegerValueTypeConstant(value, module, parameters)
}
} }
fun hasUnsignedTypesInModuleDependencies(module: ModuleDescriptor): Boolean { fun hasUnsignedTypesInModuleDependencies(module: ModuleDescriptor): Boolean {