From c07eab36fe2e17207e6efaae546a0d382513ec4c Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Sat, 12 Sep 2020 01:38:03 +0200 Subject: [PATCH] Fix #9775: Fix primitive-in-condition handling in backend isPrimitive/getPrimitive are overloaded: they both have a version which takes a symbol as input and a version which takes a tree, the latter can handle array get and set primitives which map to different JVM instructions depending on their type, but we don't care about that when emitting conditions in genCond: we only need to look for primitives which correspond to boolean operations and those are already handled by the symbol versions of isPrimitive/getPrimitive. By using these methods in genCond we avoid running some unnecessary code and we fix #9775 which was triggered because the `getPrimitive` overload we were using required forcing `lhs`. This change also aligns us with what the scalac backend does. --- .../dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 4 ++-- tests/pos/i9775.scala | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 tests/pos/i9775.scala diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 593645f0113e..cb854c24568e 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1303,7 +1303,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) tree match { - case tree @ Apply(fun, args) if isPrimitive(fun) => + case tree @ Apply(fun, args) if primitives.isPrimitive(fun.symbol) => import ScalaPrimitivesOps.{ ZNOT, ZAND, ZOR, EQ } // lhs and rhs of test @@ -1321,7 +1321,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genCond(rhs, success, failure, targetIfNoJump) } - primitives.getPrimitive(tree, lhs.tpe) match { + primitives.getPrimitive(fun.symbol) match { case ZNOT => genCond(lhs, failure, success, targetIfNoJump) case ZAND => genZandOrZor(and = true) case ZOR => genZandOrZor(and = false) diff --git a/tests/pos/i9775.scala b/tests/pos/i9775.scala new file mode 100644 index 000000000000..8d5cd5b82fa1 --- /dev/null +++ b/tests/pos/i9775.scala @@ -0,0 +1,13 @@ +trait ThreadedImpl { + private val threadSync = new AnyRef + @volatile private var wasClosed = false + + private val thread: Thread = ??? + val x: Array[Int] = ??? + + final protected def isThreadRunning: Boolean = + x(0) + // threadSync.synchronized(!wasClosed) + // true + thread.isAlive && threadSync.synchronized(!wasClosed) +}