Skip to content

Commit 98f53ee

Browse files
committed
Add check that floating point numbers are not too small
1 parent e88d077 commit 98f53ee

File tree

5 files changed

+39
-9
lines changed

5 files changed

+39
-9
lines changed

compiler/src/dotty/tools/dotc/parsing/JavaScanners.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ object JavaScanners {
521521
case FLOATLIT =>
522522
"float(" + floatVal + ")"
523523
case DOUBLELIT =>
524-
"double(" + floatVal + ")"
524+
"double(" + doubleVal + ")"
525525
case STRINGLIT =>
526526
"string(" + name + ")"
527527
case SEMI =>

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ object Parsers {
726726
case INTLIT => in.intVal(isNegated).toInt
727727
case LONGLIT => in.intVal(isNegated)
728728
case FLOATLIT => in.floatVal(isNegated).toFloat
729-
case DOUBLELIT => in.floatVal(isNegated)
729+
case DOUBLELIT => in.doubleVal(isNegated)
730730
case STRINGLIT | STRINGPART => in.strVal
731731
case TRUE => true
732732
case FALSE => false

compiler/src/dotty/tools/dotc/parsing/Scanners.scala

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,42 @@ object Scanners {
157157

158158
def intVal: Long = intVal(false)
159159

160+
private val zeroFloat = raw"[0.]+(?:[eE][+-]?[0-9]+)?[fFdD]?".r
161+
160162
/** Convert current strVal, base to double value
161163
*/
162-
def floatVal(negated: Boolean): Double = {
164+
def floatVal(negated: Boolean): Float = {
165+
assert(token == FLOATLIT)
166+
val text = removeNumberSeparators(strVal)
167+
try {
168+
val value: Float = java.lang.Float.valueOf(text).floatValue()
169+
if (value > Float.MaxValue)
170+
errorButContinue("floating point number too large")
171+
172+
if (value == 0.0f && !zeroFloat.pattern.matcher(text).matches)
173+
errorButContinue("floating point number too small")
174+
if (negated) -value else value
175+
} catch {
176+
case _: NumberFormatException =>
177+
error("malformed floating point number")
178+
0.0f
179+
}
180+
}
181+
182+
def floatVal: Float = floatVal(false)
183+
184+
/** Convert current strVal, base to double value
185+
*/
186+
def doubleVal(negated: Boolean): Double = {
187+
assert(token == DOUBLELIT)
163188
val text = removeNumberSeparators(strVal)
164-
val limit: Double =
165-
if (token == DOUBLELIT) Double.MaxValue else Float.MaxValue
166189
try {
167190
val value: Double = java.lang.Double.valueOf(text).doubleValue()
168-
if (value > limit)
169-
error("floating point number too large")
191+
if (value > Double.MaxValue)
192+
errorButContinue("double precision floating point number too large")
193+
194+
if (value == 0.0d && !zeroFloat.pattern.matcher(text).matches)
195+
errorButContinue("double precision floating point number too small")
170196
if (negated) -value else value
171197
} catch {
172198
case _: NumberFormatException =>
@@ -175,7 +201,7 @@ object Scanners {
175201
}
176202
}
177203

178-
def floatVal: Double = floatVal(false)
204+
def doubleVal: Double = doubleVal(false)
179205

180206
@inline def isNumberSeparator(c: Char): Boolean = c == '_'
181207

@@ -1034,7 +1060,7 @@ object Scanners {
10341060
case INTLIT => s"int($intVal)"
10351061
case LONGLIT => s"long($intVal)"
10361062
case FLOATLIT => s"float($floatVal)"
1037-
case DOUBLELIT => s"double($floatVal)"
1063+
case DOUBLELIT => s"double($doubleVal)"
10381064
case STRINGLIT => s"string($strVal)"
10391065
case STRINGPART => s"stringpart($strVal)"
10401066
case INTERPOLATIONID => s"interpolationid($name)"

tests/neg/t6124.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
<304..304> in t6124.scala
2+
double precision floating point number too small
13
<273..273> in t6124.scala
24
trailing separator is not allowed
35
<235..235> in t6124.scala

tests/neg/t6124.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ trait T {
1212
def r = 3.1_4_dd // error // error
1313
def s = 3_.1 // error
1414

15+
def tooSmall = 1.0E-325 // error
16+
1517
def z = 0
1618
}

0 commit comments

Comments
 (0)