From 402d96dd3fab6ae677966a9a258c00b3f34a37ed Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 30 Nov 2010 06:04:33 +0000 Subject: It looks like the fix for #2318 was causing pro... It looks like the fix for #2318 was causing problems, so I gave it some more graceful failure. Leaving #2318 open because the implementation could still work harder to find the right method. No review. --- .../scala/tools/nsc/symtab/Definitions.scala | 1 + .../scala/tools/nsc/transform/CleanUp.scala | 6 ++-- src/library/scala/runtime/ScalaRunTime.scala | 11 +++++++ test/files/run/bug2318.check | 2 ++ test/files/run/bug2318.scala | 37 ++++++++++++++++++++++ 5 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 test/files/run/bug2318.check create mode 100644 test/files/run/bug2318.scala diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 4c7bc32c02..a468e81b3e 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -164,6 +164,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { def arrayUpdateMethod = getMember(ScalaRunTimeModule, "array_update") def arrayLengthMethod = getMember(ScalaRunTimeModule, "array_length") def arrayCloneMethod = getMember(ScalaRunTimeModule, "array_clone") + def ensureAccessibleMethod = getMember(ScalaRunTimeModule, "ensureAccessible") def scalaRuntimeHash = getMember(ScalaRunTimeModule, "hash") def scalaRuntimeSameElements = getMember(ScalaRunTimeModule, nme.sameElements) diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 73886420c1..f8f185e6d8 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -221,8 +221,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { if (method != null) return method else { - method = forReceiver.getMethod("xyz", reflParams$Cache) - method.setAccessible(true) // issue #2381 + method = ScalaRunTime.ensureAccessible(forReceiver.getMethod("xyz", reflParams$Cache)) reflPoly$Cache = new SoftReference(reflPoly$Cache.get.add(forReceiver, method)) return method } @@ -250,8 +249,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym))) def cacheRHS = ((getPolyCache DOT methodCache_add)(REF(forReceiverSym), REF(methodSym))) BLOCK( - REF(methodSym) === methodSymRHS, - (REF(methodSym) DOT methodClass_setAccessible)(LIT(true)), + REF(methodSym) === (REF(ensureAccessibleMethod) APPLY (methodSymRHS)), REF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS), Return(REF(methodSym)) ) diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 2d4d1d3306..925e9b4b64 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -17,6 +17,7 @@ import scala.collection.immutable.{ NumericRange, List, Stream, Nil, :: } import scala.collection.generic.{ Sorted } import scala.xml.{ Node, MetaData } import scala.util.control.ControlThrowable +import java.lang.reflect.{ Modifier, Method => JMethod } /* The object ScalaRunTime provides ... */ @@ -111,6 +112,16 @@ object ScalaRunTime { arr } + // Java bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957 + // More background at ticket #2318. + def ensureAccessible(m: JMethod): JMethod = { + if (!m.isAccessible) { + try m setAccessible true + catch { case _: SecurityException => () } + } + m + } + def checkInitialized[T <: AnyRef](x: T): T = if (x == null) throw new UninitializedError else x diff --git a/test/files/run/bug2318.check b/test/files/run/bug2318.check new file mode 100644 index 0000000000..a486f1ac47 --- /dev/null +++ b/test/files/run/bug2318.check @@ -0,0 +1,2 @@ +bar +bar diff --git a/test/files/run/bug2318.scala b/test/files/run/bug2318.scala new file mode 100644 index 0000000000..8347ed8e7b --- /dev/null +++ b/test/files/run/bug2318.scala @@ -0,0 +1,37 @@ +import java.security._ + +object Test { + trait Bar { def bar: Unit } + + object Mgr extends SecurityManager { + override def checkPermission(perm: Permission) = perm match { + case _: java.lang.RuntimePermission => () + case _: java.io.FilePermission => () + case _ => super.checkPermission(perm) + } + } + + def bug1() = { + val p = Runtime.getRuntime().exec("ls"); + type Destroyable = { def destroy() : Unit } + def doDestroy( obj : Destroyable ) : Unit = obj.destroy(); + doDestroy( p ); + } + def bug2() = { + System.setSecurityManager(Mgr) + + val b = new Bar { def bar = println("bar") } + b.bar + + val structural = b.asInstanceOf[{ def bar: Unit }] + structural.bar + } + + def main(args: Array[String]) { + // figuring this will otherwise break on windows + try bug1() + catch { case _: java.io.IOException => () } + + bug2() + } +} -- cgit v1.2.3