diff --git a/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala b/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala index c69b342b9a01..13540cf2bbf1 100644 --- a/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala +++ b/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala @@ -434,7 +434,7 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer: * they shouldn't be lifted. */ val sym = fun.symbol - sym.exists && (isShortCircuitedOp(sym) || StringInterpolatorOpt.isCompilerIntrinsic(sym)) + sym.exists && (isShortCircuitedOp(sym) || StringInterpolatorOpt.isCompilerIntrinsic(sym) || sym == defn.Object_synchronized) end val fun = tree.fun diff --git a/tests/run/i16940.scala b/tests/run/i16940.scala new file mode 100644 index 000000000000..5c16b6d3333d --- /dev/null +++ b/tests/run/i16940.scala @@ -0,0 +1,30 @@ +// scalac: -coverage-out:coverage +// scalajs: --skip + +import concurrent.ExecutionContext.Implicits.global +import scala.concurrent.* +import scala.concurrent.duration.* + +var test = 0 + +def brokenSynchronizedBlock(option: Boolean): Future[Unit] = Future { + if (option) { + Thread.sleep(500) + } + synchronized { + val tmp = test + Thread.sleep(1000) + test = tmp + 1 + } +} + +object Test extends App { + Await.result( + Future.sequence(Seq(brokenSynchronizedBlock(false), brokenSynchronizedBlock(true))) + .map { result => + println(test) + assert(test == 2) + }, + 3.seconds + ) +}