Skip to content

Commit f8907f1

Browse files
authored
Merge pull request #3842 from dotty-staging/cyclic-unpickling
Add cyclic reference detection to TASTY unpickling
2 parents 6c6cd96 + 2bf3fdd commit f8907f1

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,16 @@ class TreeUnpickler(reader: TastyReader,
631631
* or else read definition.
632632
*/
633633
def readIndexedDef()(implicit ctx: Context): Tree = treeAtAddr.remove(currentAddr) match {
634-
case Some(tree) => skipTree(); tree
635-
case none => readNewDef()
634+
case Some(tree) =>
635+
assert(tree != PoisonTree, s"Cyclic reference while unpickling definition at address ${currentAddr.index} in unit ${ctx.compilationUnit}")
636+
skipTree()
637+
tree
638+
case none =>
639+
val start = currentAddr
640+
treeAtAddr(start) = PoisonTree
641+
val tree = readNewDef()
642+
treeAtAddr.remove(start)
643+
tree
636644
}
637645

638646
private def readNewDef()(implicit ctx: Context): Tree = {
@@ -1169,6 +1177,9 @@ class TreeUnpickler(reader: TastyReader,
11691177

11701178
object TreeUnpickler {
11711179

1180+
/** A marker value used to detect cyclic reference while unpickling definitions. */
1181+
@sharable val PoisonTree: tpd.Tree = Thicket(Nil)
1182+
11721183
/** An enumeration indicating which subtrees should be added to an OwnerTree. */
11731184
type MemberDefMode = Int
11741185
final val MemberDefsOnly = 0 // add only member defs; skip other statements

0 commit comments

Comments
 (0)