Skip to content

Synchronized nested method can be incorrectly marked as static #11331

@rfkm

Description

@rfkm

Hi,

I'd been investigating deadlock trouble on my Scala application and found Scala compiler seemed to emit unexpected code.

In the following code, it seems the compiler wrongly marks g as static even though it refers to self. It looks like it doesn't take self.synchronized into account when optimizing a nested method.

class C { self =>
  def f = {
    def g(f: => Unit) = self.synchronized(f)
    g {
      println("self is locked?: " + Thread.holdsLock(self))
      println("classOf[C] is locked?: " + Thread.holdsLock(classOf[C]))
    }
  }
}

object Test {
  def main(args: Array[String]): Unit = {
    new C().f
    // Output:
    //  self is locked?: false
    //  classOf[C] is locked?: true
  }
}

Bytecode:

private static final synchronized void g$1(scala.Function0);

It looks like this was introduced since 2.12.x.
I can reproduce this with 2.12.8, 2.13.0-M5.
Related PR (maybe): scala/scala#5099

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions