diff options
author | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2014-02-22 19:36:30 +0100 |
---|---|---|
committer | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2014-02-22 19:36:30 +0100 |
commit | 880f925b69c057ae954c01e3e93863855dd67e27 (patch) | |
tree | f4bd08050f4be0c6bcb9f4f5f638e383be4c1469 /src/compiler | |
parent | c2d6fc6fa1124ff5d4d46e0d97e5552d0f2a06a1 (diff) | |
parent | 5dfcf5eb6a2fea69327420a3ebc4792f9365bf5a (diff) | |
download | scala-880f925b69c057ae954c01e3e93863855dd67e27.tar.gz scala-880f925b69c057ae954c01e3e93863855dd67e27.tar.bz2 scala-880f925b69c057ae954c01e3e93863855dd67e27.zip |
Merge pull request #3573 from retronym/ticket/8324
SI-8324 Fix regression in override checks for sealed classes
Diffstat (limited to 'src/compiler')
5 files changed, 12 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala index 2e44c405cf..676ee12683 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala @@ -415,7 +415,7 @@ abstract class TypeFlowAnalysis { } val concreteMethod = inliner.lookupImplFor(msym, receiver) val isCandidate = { - ( inliner.isClosureClass(receiver) || concreteMethod.isEffectivelyFinal || receiver.isEffectivelyFinal ) && + ( inliner.isClosureClass(receiver) || concreteMethod.isEffectivelyFinalOrNotOverridden || receiver.isEffectivelyFinalOrNotOverridden ) && !blackballed(concreteMethod) } if(isCandidate) { @@ -501,7 +501,7 @@ abstract class TypeFlowAnalysis { } private def isReceiverKnown(cm: opcodes.CALL_METHOD): Boolean = { - cm.method.isEffectivelyFinal && cm.method.owner.isEffectivelyFinal + cm.method.isEffectivelyFinalOrNotOverridden && cm.method.owner.isEffectivelyFinalOrNotOverridden } private def putOnRadar(blocks: Traversable[BasicBlock]) { diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index b39fee65bb..90c37ba0b3 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -433,7 +433,7 @@ abstract class DeadCodeElimination extends SubComponent { } private def isPure(sym: Symbol) = ( - (sym.isGetter && sym.isEffectivelyFinal && !sym.isLazy) + (sym.isGetter && sym.isEffectivelyFinalOrNotOverridden && !sym.isLazy) || (sym.isPrimaryConstructor && (sym.enclosingPackage == RuntimePackage || inliner.isClosureClass(sym.owner))) ) /** Is 'sym' a side-effecting method? TODO: proper analysis. */ diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index fa424584b2..f6de522d09 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -72,8 +72,8 @@ abstract class Inliners extends SubComponent { def needsLookup = ( (clazz != NoSymbol) && (clazz != sym.owner) - && !sym.isEffectivelyFinal - && clazz.isEffectivelyFinal + && !sym.isEffectivelyFinalOrNotOverridden + && clazz.isEffectivelyFinalOrNotOverridden ) def lookup(clazz: Symbol): Symbol = { // println("\t\tlooking up " + meth + " in " + clazz.fullName + " meth.owner = " + meth.owner) @@ -362,7 +362,7 @@ abstract class Inliners extends SubComponent { for(x <- inputBlocks; easyCake = callsites(x); if easyCake.nonEmpty) { breakable { for(ocm <- easyCake) { - assert(ocm.method.isEffectivelyFinal && ocm.method.owner.isEffectivelyFinal) + assert(ocm.method.isEffectivelyFinalOrNotOverridden && ocm.method.owner.isEffectivelyFinalOrNotOverridden) if(analyzeInc(ocm, x, ocm.method.owner, -1, ocm.method)) { inlineCount += 1 break() @@ -409,8 +409,8 @@ abstract class Inliners extends SubComponent { def isCandidate = ( isClosureClass(receiver) - || concreteMethod.isEffectivelyFinal - || receiver.isEffectivelyFinal + || concreteMethod.isEffectivelyFinalOrNotOverridden + || receiver.isEffectivelyFinalOrNotOverridden ) def isApply = concreteMethod.name == nme.apply @@ -425,7 +425,7 @@ abstract class Inliners extends SubComponent { debuglog("Treating " + i + "\n\treceiver: " + receiver + "\n\ticodes.available: " + isAvailable - + "\n\tconcreteMethod.isEffectivelyFinal: " + concreteMethod.isEffectivelyFinal) + + "\n\tconcreteMethod.isEffectivelyFinalOrNotOverridden: " + concreteMethod.isEffectivelyFinalOrNotOverridden) if (!isCandidate) warnNoInline("it can be overridden") else if (!isAvailable) warnNoInline("bytecode unavailable") @@ -592,7 +592,7 @@ abstract class Inliners extends SubComponent { /** Should method 'sym' being called in 'receiver' be loaded from disk? */ def shouldLoadImplFor(sym: Symbol, receiver: Symbol): Boolean = { def alwaysLoad = (receiver.enclosingPackage == RuntimePackage) || (receiver == PredefModule.moduleClass) - def loadCondition = sym.isEffectivelyFinal && isMonadicMethod(sym) && isHigherOrderMethod(sym) + def loadCondition = sym.isEffectivelyFinalOrNotOverridden && isMonadicMethod(sym) && isHigherOrderMethod(sym) val res = hasInline(sym) || alwaysLoad || loadCondition debuglog("shouldLoadImplFor: " + receiver + "." + sym + ": " + res) diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index 5973c70583..714f189ead 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -116,7 +116,7 @@ abstract class TailCalls extends Transform { def tailLabels: Set[Symbol] def enclosingType = method.enclClass.typeOfThis - def isEligible = method.isEffectivelyFinal + def isEligible = method.isEffectivelyFinalOrNotOverridden def isMandatory = method.hasAnnotation(TailrecClass) def isTransformed = isEligible && accessed(label) diff --git a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala index b899cd8994..13884404b3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala @@ -203,7 +203,7 @@ trait Checkable { private def isSealedOrFinal(sym: Symbol) = sym.isSealed || sym.isFinal private def isEffectivelyFinal(sym: Symbol): Boolean = ( // initialization important - sym.initialize.isEffectivelyFinal || ( + sym.initialize.isEffectivelyFinalOrNotOverridden || ( settings.future && isTupleSymbol(sym) // SI-7294 step into the future and treat TupleN as final. ) ) |