Skip to content

Commit 2e606a8

Browse files
committed
Merge pull request #836 from dotty-staging/lazy-vals-longs
LazyVals: fix underflows in binary shifts.
2 parents 2b5b064 + cffd494 commit 2e606a8

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

src/dotty/runtime/LazyVals.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import scala.annotation.tailrec
88
object LazyVals {
99
private val unsafe = scala.concurrent.util.Unsafe.instance
1010

11-
final val BITS_PER_LAZY_VAL = 2
12-
final val LAZY_VAL_MASK = 3
11+
final val BITS_PER_LAZY_VAL = 2L
12+
final val LAZY_VAL_MASK = 3L
1313

1414
@inline def STATE(cur: Long, ord: Int) = (cur >> (ord * BITS_PER_LAZY_VAL)) & LAZY_VAL_MASK
1515
@inline def CAS(t: Object, offset: Long, e: Long, v: Int, ord: Int) = {

src/dotty/tools/dotc/transform/LazyVals.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
341341
// compute or create appropriate offsetSymol, bitmap and bits used by current ValDef
342342
appendOffsetDefs.get(companion.moduleClass) match {
343343
case Some(info) =>
344-
val flagsPerLong = 64 / dotty.runtime.LazyVals.BITS_PER_LAZY_VAL
344+
val flagsPerLong = (64 / dotty.runtime.LazyVals.BITS_PER_LAZY_VAL).toInt
345345
info.ord += 1
346346
ord = info.ord % flagsPerLong
347347
val id = info.ord / flagsPerLong

tests/run/LazyValsLongs.scala

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
class I {
2+
object A1
3+
object A2
4+
object A3
5+
object A4
6+
object A5
7+
object A6
8+
object A7
9+
object A8
10+
object A9
11+
object A10
12+
object A11
13+
object A12
14+
object A13
15+
object A14
16+
object A15
17+
object A16
18+
object A17
19+
object A18
20+
}
21+
22+
object Test {
23+
def main(args: Array[String]): Unit = {
24+
val c = new I
25+
import c._
26+
val l1 = List(A1,
27+
A2,
28+
A3,
29+
A4,
30+
A5,
31+
A6,
32+
A7,
33+
A8,
34+
A9,
35+
A10,
36+
A11,
37+
A12,
38+
A13,
39+
A14,
40+
A15,
41+
A16,
42+
A17,
43+
A18)
44+
val l2 = List(A1,
45+
A2,
46+
A3,
47+
A4,
48+
A5,
49+
A6,
50+
A7,
51+
A8,
52+
A9,
53+
A10,
54+
A11,
55+
A12,
56+
A13,
57+
A14,
58+
A15,
59+
A16,
60+
A17,
61+
A18)
62+
assert(l1.mkString == l2.mkString)
63+
assert(!l1.contains(null))
64+
}
65+
}

0 commit comments

Comments
 (0)