Skip to content

Backend crash when inlined method contains try #2056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
smarter opened this issue Mar 7, 2017 · 5 comments
Closed

Backend crash when inlined method contains try #2056

smarter opened this issue Mar 7, 2017 · 5 comments

Comments

@smarter
Copy link
Member

smarter commented Mar 7, 2017

object Test {
  inline def crash() = {
    try {
      println("hi")
    }
  }

  def main(args: Array[String]): Unit = {
    crash()
  }
}
Unexpected tree in genLoad: EmptyTree/class dotty.tools.dotc.ast.Trees$Thicket at: <no position>
java.lang.RuntimeException: Unexpected tree in genLoad: EmptyTree/class dotty.tools.dotc.ast.Trees$Thicket at: <no position>
        at dotty.tools.backend.jvm.DottyBackendInterface.abort(DottyBackendInterface.scala:381)
        at scala.tools.nsc.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:431)
        at scala.tools.nsc.backend.jvm.BCodeSyncAndTry$SyncAndTryBuilder.emitFinalizer(BCodeSyncAndTry.scala:376)
        at scala.tools.nsc.backend.jvm.BCodeSyncAndTry$SyncAndTryBuilder.genLoadTry(BCodeSyncAndTry.scala:293)
        at scala.tools.nsc.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:307)
        at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.emitNormalMethodBody$1(BCodeSkelBuilder.scala:607)
        at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genDefDef(BCodeSkelBuilder.scala:641)
        at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen(BCodeSkelBuilder.scala:510)
        at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen(BCodeSkelBuilder.scala:512)
        at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genPlainClass(BCodeSkelBuilder.scala:119)
        at dotty.tools.backend.jvm.GenBCodePipeline$Worker1.visit(GenBCode.scala:201)
        at dotty.tools.backend.jvm.GenBCodePipeline$Worker1.run(GenBCode.scala:154)
        at dotty.tools.backend.jvm.GenBCodePipeline.buildAndSendToDisk(GenBCode.scala:357)
        at dotty.tools.backend.jvm.GenBCodePipeline.run(GenBCode.scala:323)
        at dotty.tools.backend.jvm.GenBCode.run(GenBCode.scala:56)
        at dotty.tools.dotc.core.Phases$Phase$$anonfun$runOn$1.apply(Phases.scala:283)
        at dotty.tools.dotc.core.Phases$Phase$$anonfun$runOn$1.apply(Phases.scala:281)
        at scala.collection.immutable.List.map(List.scala:273)
        at dotty.tools.dotc.core.Phases$Phase$class.runOn(Phases.scala:281)
        at dotty.tools.backend.jvm.GenBCode.runOn(GenBCode.scala:40)
        at dotty.tools.dotc.Run$$anonfun$compileUnits$1$$anonfun$apply$mcV$sp$1.apply(Run.scala:76)
        at dotty.tools.dotc.Run$$anonfun$compileUnits$1$$anonfun$apply$mcV$sp$1.apply(Run.scala:73)
        at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
        at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186)
        at dotty.tools.dotc.Run$$anonfun$compileUnits$1.apply$mcV$sp(Run.scala:73)
        at dotty.tools.dotc.Run$$anonfun$compileUnits$1.apply(Run.scala:67)
        at dotty.tools.dotc.Run$$anonfun$compileUnits$1.apply(Run.scala:67)
        at dotty.tools.dotc.util.Stats$.monitorHeartBeat(Stats.scala:76)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:67)
        at dotty.tools.dotc.Run.compileSources(Run.scala:64)
        at dotty.tools.dotc.Run.compile(Run.scala:48)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:26)
        at dotty.tools.dotc.Driver.process(Driver.scala:124)
        at dotty.tools.dotc.Driver.process(Driver.scala:93)
        at dotty.tools.dotc.Driver.process(Driver.scala:105)
        at dotty.tools.dotc.Driver.main(Driver.scala:132)
        at dotty.tools.dotc.Main.main(Main.scala)
@DarkDimius
Copy link
Contributor

It's not due to backend.
We should augment Ycheck to ensure that there are no Thickets\EmptyTrees.

@smarter
Copy link
Member Author

smarter commented Mar 7, 2017

We should augment Ycheck to ensure that there are no Thickets\EmptyTrees.

Are you sure? There are many cases where EmptyTree reaches backend, for example here's the tree for an empty class at genBCode (all the Thicket(List()) are just EmptyTree):

PackageDef(Ident(<empty>), List(
  TypeDef(Test, 
    Template(
      DefDef(<init>, List(), List(List()), TypeTree(), 
        Block(List(
          Apply(Select(Super(This(Ident(Test)), Ident()), <init>), List())
        ), Literal(()))
      )
    , List(TypeTree()), ValDef(_, Thicket(List()), Thicket(List())), List())
  )
))

@smarter
Copy link
Member Author

smarter commented Mar 7, 2017

Here's the tree of my original example that crashes:

PackageDef(Ident(<empty>), List(
  TypeDef(Test$, 
    Template(
      DefDef(<init>, List(), List(List()), TypeTree(), 
        Block(List(
          Apply(Select(Super(This(Ident(Test$)), Ident()), <init>), List())
        ), Literal(()))
      )
    , List(TypeTree()), ValDef(_, Thicket(List()), Thicket(List())), List(
      DefDef(crash, List(), List(List()), TypeTree(), 
        Try(Apply(Ident(println), List(Literal("hi"))), List(), Thicket(List()))
      )
    ,
      DefDef(main, List(), List(List(ValDef(args, TypeTree(), Thicket(List()))))
        , 
      TypeTree(), 
        Try(Apply(Ident(println), List(Literal("hi"))), List(), Thicket(List()))
      )
    ))
  )
,ValDef(Test, TypeTree(), Apply(Select(New(TypeTree()), <init>), List()))))

I can't see any difference between crash (which compiles fine by itself) and main (which causes the crash)

@DarkDimius
Copy link
Contributor

@smarter, I've meant the method bodies. The Backend ignores the high-level tree structure of packages and classes and uses types instead.

@smarter
Copy link
Member Author

smarter commented Mar 7, 2017

Found the issue, will make a PR soon.

smarter added a commit to dotty-staging/dotty that referenced this issue Mar 7, 2017
In various places we do "case EmptyTree =>", since Tree#equals uses
reference equality this means that EmptyTree should never be copied,
otherwise some other code path will be taken.
smarter added a commit to dotty-staging/dotty that referenced this issue Mar 7, 2017
In various places we do "case EmptyTree =>", since Tree#equals uses
reference equality this means that EmptyTree should never be copied,
otherwise some other code path will be taken.
@odersky odersky closed this as completed in 094cd9f Mar 7, 2017
odersky added a commit that referenced this issue Mar 7, 2017
Fix #2056: Backend crash when inlined method contains try
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants