Skip to content

Commit 935f7b1

Browse files
committed
Add warning if constant conforms to infinity or zero
#KT-3805 Fixed
1 parent 292f010 commit 935f7b1

File tree

7 files changed

+78
-4
lines changed

7 files changed

+78
-4
lines changed

compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010-2016 JetBrains s.r.o.
2+
* Copyright 2010-2017 JetBrains s.r.o.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -790,6 +790,8 @@ enum BadNamedArgumentsTarget {
790790
DiagnosticFactory0<KtConstantExpression> WRONG_LONG_SUFFIX = DiagnosticFactory0.create(ERROR, LONG_LITERAL_SUFFIX);
791791
DiagnosticFactory0<KtConstantExpression> INT_LITERAL_OUT_OF_RANGE = DiagnosticFactory0.create(ERROR);
792792
DiagnosticFactory0<KtConstantExpression> FLOAT_LITERAL_OUT_OF_RANGE = DiagnosticFactory0.create(ERROR);
793+
DiagnosticFactory0<KtConstantExpression> FLOAT_LITERAL_CONFORMS_INFINITY = DiagnosticFactory0.create(WARNING);
794+
DiagnosticFactory0<KtConstantExpression> FLOAT_LITERAL_CONFORMS_ZERO = DiagnosticFactory0.create(WARNING);
793795
DiagnosticFactory2<KtConstantExpression, String, KotlinType> CONSTANT_EXPECTED_TYPE_MISMATCH = DiagnosticFactory2.create(ERROR);
794796
DiagnosticFactory0<KtConstantExpression> INCORRECT_CHARACTER_LITERAL = DiagnosticFactory0.create(ERROR);
795797
DiagnosticFactory0<KtConstantExpression> EMPTY_CHARACTER_LITERAL = DiagnosticFactory0.create(ERROR);

compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010-2016 JetBrains s.r.o.
2+
* Copyright 2010-2017 JetBrains s.r.o.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -534,6 +534,8 @@ public String render(@NotNull KtExpression expression, @NotNull RenderingContext
534534
MAP.put(INT_LITERAL_OUT_OF_RANGE, "The value is out of range");
535535
MAP.put(WRONG_LONG_SUFFIX, "Use 'L' instead of 'l'");
536536
MAP.put(FLOAT_LITERAL_OUT_OF_RANGE, "The value is out of range");
537+
MAP.put(FLOAT_LITERAL_CONFORMS_INFINITY, "Floating point number conforms to infinity");
538+
MAP.put(FLOAT_LITERAL_CONFORMS_ZERO, "Floating point number conforms to zero");
537539
MAP.put(INCORRECT_CHARACTER_LITERAL, "Incorrect character literal");
538540
MAP.put(EMPTY_CHARACTER_LITERAL, "Empty character literal");
539541
MAP.put(ILLEGAL_UNDERSCORE, "Illegal underscore");

compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve.constants.evaluate
1818

1919
import com.intellij.psi.tree.IElementType
2020
import com.intellij.psi.util.PsiTreeUtil
21+
import com.intellij.psi.util.TypeConversionUtil
2122
import com.intellij.util.text.LiteralFormatUtil
2223
import org.jetbrains.kotlin.KtNodeTypes
2324
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
@@ -313,8 +314,26 @@ private class ConstantExpressionEvaluatorVisitor(
313314
else -> throw IllegalArgumentException("Unsupported constant: " + expression)
314315
} ?: return null
315316

316-
fun isLongWithSuffix() = nodeElementType == KtNodeTypes.INTEGER_CONSTANT && hasLongSuffix(text)
317-
return createConstant(result, expectedType, CompileTimeConstant.Parameters(true, !isLongWithSuffix(), false, usesNonConstValAsConstant = false))
317+
if (result is Double) {
318+
if (result.isInfinite()) {
319+
trace.report(Errors.FLOAT_LITERAL_CONFORMS_INFINITY.on(expression))
320+
}
321+
if (result == 0.0 && !TypeConversionUtil.isFPZero(text)) {
322+
trace.report(Errors.FLOAT_LITERAL_CONFORMS_ZERO.on(expression))
323+
}
324+
}
325+
326+
if (result is Float) {
327+
if (result.isInfinite()) {
328+
trace.report(Errors.FLOAT_LITERAL_CONFORMS_INFINITY.on(expression))
329+
}
330+
if (result == 0.0f && !TypeConversionUtil.isFPZero(text)) {
331+
trace.report(Errors.FLOAT_LITERAL_CONFORMS_ZERO.on(expression))
332+
}
333+
}
334+
335+
val isLongWithSuffix = nodeElementType == KtNodeTypes.INTEGER_CONSTANT && hasLongSuffix(text)
336+
return createConstant(result, expectedType, CompileTimeConstant.Parameters(true, !isLongWithSuffix, false, usesNonConstValAsConstant = false))
318337
}
319338

320339
override fun visitParenthesizedExpression(expression: KtParenthesizedExpression, expectedType: KotlinType?): CompileTimeConstant<*>? {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// !DIAGNOSTICS: -UNUSED_VARIABLE, -UNUSED_EXPRESSION
2+
3+
fun test() {
4+
<!FLOAT_LITERAL_CONFORMS_INFINITY!>1.2E400F<!>
5+
<!FLOAT_LITERAL_CONFORMS_ZERO!>1.2E-400F<!>
6+
<!FLOAT_LITERAL_CONFORMS_INFINITY!>11111111111111111111111111111111111111111111111111111111111111111F<!>
7+
<!FLOAT_LITERAL_CONFORMS_ZERO!>0.000000000000000000000000000000000000000000000000000000000000001F<!>
8+
0.000000000000000000000000000000000000001000000000000000000000000F
9+
10+
<!FLOAT_LITERAL_CONFORMS_INFINITY!>1.2E400f<!>
11+
<!FLOAT_LITERAL_CONFORMS_ZERO!>1.2E-400f<!>
12+
<!FLOAT_LITERAL_CONFORMS_INFINITY!>11111111111111111111111111111111111111111111111111111111111111111f<!>
13+
<!FLOAT_LITERAL_CONFORMS_ZERO!>0.000000000000000000000000000000000000000000000000000000000000001f<!>
14+
0.000000000000000000000000000000000000001000000000000000000000000f
15+
16+
val d1: Double = <!FLOAT_LITERAL_CONFORMS_INFINITY!>1.2E400<!>
17+
val d2: Double = <!FLOAT_LITERAL_CONFORMS_ZERO!>1.2E-400<!>
18+
val d3: Double = 11111111111111111111111111111111111111111111111111111111111111111.0
19+
val d4: Double = 0.000000000000000000000000000000000000000000000000000000000000001
20+
val d5: Double = 0.000000000000000000000000000000000000001000000000000000000000000
21+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package
2+
3+
public fun test(): kotlin.Unit

compiler/testData/evaluate/constant/floatsAndDoubles.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,24 @@ val prop8: Float = 1.0.toDouble() + 1.0
2626

2727
// val prop9: -2.0.toDouble()
2828
val prop9: Double = -2.0
29+
30+
// val prop10: Infinity.toFloat()
31+
val prop10: Float = 1.2E400F
32+
33+
// val prop11: 0.0.toFloat()
34+
val prop11: Float = 1.2E-400F
35+
36+
// val prop12: Infinity.toFloat()
37+
val prop12: Float = 11111111111111111111111111111111111111111111111111111111111111111F
38+
39+
// val prop13: 0.0.toFloat()
40+
val prop13: Float = 0.000000000000000000000000000000000000000000000000000000000000001F
41+
42+
// val prop14: 1.0E-39.toFloat()
43+
val prop14: Float = 0.000000000000000000000000000000000000001000000000000000000000000F
44+
45+
// val prop15: Infinity.toDouble()
46+
val prop15: Double = 1.2E400
47+
48+
// val prop16: 0.0.toDouble()
49+
val prop16: Double = 1.2E-400

compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7372,6 +7372,12 @@ public void testFloat() throws Exception {
73727372
doTest(fileName);
73737373
}
73747374

7375+
@TestMetadata("floatLiteralOutOfRange.kt")
7376+
public void testFloatLiteralOutOfRange() throws Exception {
7377+
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/evaluate/floatLiteralOutOfRange.kt");
7378+
doTest(fileName);
7379+
}
7380+
73757381
@TestMetadata("intOverflow.kt")
73767382
public void testIntOverflow() throws Exception {
73777383
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/evaluate/intOverflow.kt");

0 commit comments

Comments
 (0)