From 824103644337758f2a6a70ea69a33a9671e1e69c Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Fri, 18 Nov 2016 14:56:13 +1000 Subject: SI-9814 Fix synchronized in specialized overrides Specialization creates a subclasses of a specializd class for each type parameter combination. These contains copies of the methods from the superclass. However, before this transform, the pattern of self-synchronization in a method body had been replace by flag Flag.SYNCHRONIZED on the method symbol. This was not being propagated to the override, and hence no locking occured. This commit modifies the creation of the specialized overload symbol to copy the SYNCHRONIZED flag, as was already done for ASBOVERRIDE. I have also done the same for the `@strictfp` annotation. --- .../tools/nsc/transform/SpecializeTypes.scala | 3 ++- test/files/run/t9814.scala | 28 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 test/files/run/t9814.scala diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index c171050bbd..84f47c1caa 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1049,7 +1049,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } } debuglog(s"specialized overload $om for ${overriding.name.decode} in ${pp(env)}: ${om.info}") - if (overriding.isAbstractOverride) om.setFlag(ABSOVERRIDE) + om.setFlag(overriding.flags & (ABSOVERRIDE | SYNCHRONIZED)) + om.withAnnotations(overriding.annotations.filter(_.symbol == ScalaStrictFPAttr)) typeEnv(om) = env addConcreteSpecMethod(overriding) if (overriding.isDeferred) { // abstract override diff --git a/test/files/run/t9814.scala b/test/files/run/t9814.scala new file mode 100644 index 0000000000..3aef3928f6 --- /dev/null +++ b/test/files/run/t9814.scala @@ -0,0 +1,28 @@ +import java.lang.reflect.Modifier + +import scala.annotation.strictfp + +class Foo extends (() => Unit) { + def apply(): Unit = synchronized { + // we're in a specialized subclass + assert(Thread.currentThread.getStackTrace.apply(1).getMethodName == "apply$mcV$sp") + assert(Thread.holdsLock(this)) + } +} + +class Bar extends (() => Unit) { + @strictfp def apply(): Unit = synchronized { + // we're in a specialized subclass + assert(Thread.currentThread.getStackTrace.apply(1).getMethodName == "apply$mcV$sp") + assert(Thread.holdsLock(this)) + } +} + +object Test { + def main(args: Array[String]): Unit = { + new Foo().apply() + + val m = classOf[Bar].getDeclaredMethod("apply$mcV$sp") + assert(Modifier.isStrict(m.getModifiers)) + } +} -- cgit v1.2.3