From 18efdedfb97de7ca9f6f6ce385194d5a6902769d Mon Sep 17 00:00:00 2001 From: Hubert Plociniczak Date: Wed, 9 May 2012 22:33:09 +0200 Subject: Better fix for SI-5676. Review by @paulp --- .../scala/tools/nsc/backend/jvm/GenASM.scala | 7 +++--- .../scala/tools/nsc/backend/jvm/GenJVM.scala | 6 ++++-- test/files/run/t5676.check | 3 +++ test/files/run/t5676.flags | 1 + test/files/run/t5676.scala | 24 +++++++++++++++++++++ test/pending/run/t5676.flags | 1 - test/pending/run/t5676.scala | 25 ---------------------- 7 files changed, 36 insertions(+), 31 deletions(-) create mode 100644 test/files/run/t5676.check create mode 100644 test/files/run/t5676.flags create mode 100644 test/files/run/t5676.scala delete mode 100644 test/pending/run/t5676.flags delete mode 100644 test/pending/run/t5676.scala diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index aa8f469513..225afaf0fb 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -274,8 +274,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters { // we can exclude lateFINAL. Such symbols are eligible for inlining, but to // avoid breaking proxy software which depends on subclassing, we do not // emit ACC_FINAL. + // Nested objects won't receive ACC_FINAL in order to allow for their overloading. + val finalFlag = ( - ((sym.rawflags & (Flags.FINAL | Flags.MODULE)) != 0) + (sym.hasFlag(Flags.FINAL) || isTopLevelModule(sym)) && !sym.enclClass.isInterface && !sym.isClassConstructor && !sym.isMutable // lazy vals and vars both @@ -649,8 +651,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { val INNER_CLASSES_FLAGS = (asm.Opcodes.ACC_PUBLIC | asm.Opcodes.ACC_PRIVATE | asm.Opcodes.ACC_PROTECTED | - asm.Opcodes.ACC_STATIC | asm.Opcodes.ACC_FINAL | - asm.Opcodes.ACC_INTERFACE | asm.Opcodes.ACC_ABSTRACT) + asm.Opcodes.ACC_STATIC | asm.Opcodes.ACC_INTERFACE | asm.Opcodes.ACC_ABSTRACT) val PublicStatic = asm.Opcodes.ACC_PUBLIC | asm.Opcodes.ACC_STATIC val PublicStaticFinal = asm.Opcodes.ACC_PUBLIC | asm.Opcodes.ACC_STATIC | asm.Opcodes.ACC_FINAL diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 042e739abe..f303a8d3fa 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -191,7 +191,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with val MIN_SWITCH_DENSITY = 0.7 val INNER_CLASSES_FLAGS = - (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT) + (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_INTERFACE | ACC_ABSTRACT) val PublicStatic = ACC_PUBLIC | ACC_STATIC val PublicStaticFinal = ACC_PUBLIC | ACC_STATIC | ACC_FINAL @@ -1954,8 +1954,10 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with // we can exclude lateFINAL. Such symbols are eligible for inlining, but to // avoid breaking proxy software which depends on subclassing, we do not // emit ACC_FINAL. + // Nested objects won't receive ACC_FINAL in order to allow for their overloading. + val finalFlag = ( - ((sym.rawflags & (Flags.FINAL | Flags.MODULE)) != 0) + (sym.hasFlag(Flags.FINAL) || isTopLevelModule(sym)) && !sym.enclClass.isInterface && !sym.isClassConstructor && !sym.isMutable // lazy vals and vars both diff --git a/test/files/run/t5676.check b/test/files/run/t5676.check new file mode 100644 index 0000000000..3b562d3046 --- /dev/null +++ b/test/files/run/t5676.check @@ -0,0 +1,3 @@ +ok +false +true diff --git a/test/files/run/t5676.flags b/test/files/run/t5676.flags new file mode 100644 index 0000000000..e1b37447c9 --- /dev/null +++ b/test/files/run/t5676.flags @@ -0,0 +1 @@ +-Xexperimental \ No newline at end of file diff --git a/test/files/run/t5676.scala b/test/files/run/t5676.scala new file mode 100644 index 0000000000..b643c300ce --- /dev/null +++ b/test/files/run/t5676.scala @@ -0,0 +1,24 @@ +import java.lang.reflect.Modifier + +class Bar[T] + +class Foo[T] { + object A extends Bar[T] +} + +class Baz[S] extends Foo[S] { + override object A extends Bar[S] { + def foo(): String = "ok" + } +} + +object Test { + + def main(a: Array[String]) { + val b = new Baz[Any] + println(b.A.foo()) + println(Modifier.isFinal(classOf[Baz[Any]].getModifiers())) + println(Modifier.isFinal(Test.getClass.getModifiers())) + } + +} diff --git a/test/pending/run/t5676.flags b/test/pending/run/t5676.flags deleted file mode 100644 index e1b37447c9..0000000000 --- a/test/pending/run/t5676.flags +++ /dev/null @@ -1 +0,0 @@ --Xexperimental \ No newline at end of file diff --git a/test/pending/run/t5676.scala b/test/pending/run/t5676.scala deleted file mode 100644 index 3ff498eaa2..0000000000 --- a/test/pending/run/t5676.scala +++ /dev/null @@ -1,25 +0,0 @@ - - - - -class Bar[T] - - -class Foo[T] { - object A extends Bar[T] -} - - -class Baz[S] extends Foo[S] { - override object A extends Bar[S] -} - - -object Test { - - def main(a: Array[String]) { - val b = new Baz[Any] - println(b) - } - -} -- cgit v1.2.3