summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/internal/ClassfileConstants.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-08-16 18:01:39 +0200
committerJason Zaugg <jzaugg@gmail.com>2013-08-16 18:01:39 +0200
commitab8a223c6c01c1a725c9892c04952f6451aedf0d (patch)
tree37c7d98c711e47c9fd5670323c86b5f35fa8b1b5 /src/reflect/scala/reflect/internal/ClassfileConstants.scala
parent8053c197941608b06089de4a618615d46552aa0b (diff)
downloadscala-ab8a223c6c01c1a725c9892c04952f6451aedf0d.tar.gz
scala-ab8a223c6c01c1a725c9892c04952f6451aedf0d.tar.bz2
scala-ab8a223c6c01c1a725c9892c04952f6451aedf0d.zip
SI-7603 Fix thread safety of FlagTranslation
This is outside of the Global cake, so we can't assume single threaded access. A var was introduced in af3daf6fdb that can lead to incorrect flag interpretation. The reported bug was triggered in a multi-project SBT build. Java Annotations read from classfiles were occasionally conferred the TRAIT|INFERFACE|ABSTRACT flag set, leading to "@Foo is abstract, cannot be instatiated" later down the line.
Diffstat (limited to 'src/reflect/scala/reflect/internal/ClassfileConstants.scala')
-rw-r--r--src/reflect/scala/reflect/internal/ClassfileConstants.scala36
1 files changed, 14 insertions, 22 deletions
diff --git a/src/reflect/scala/reflect/internal/ClassfileConstants.scala b/src/reflect/scala/reflect/internal/ClassfileConstants.scala
index c198271fb1..eb70ff3f17 100644
--- a/src/reflect/scala/reflect/internal/ClassfileConstants.scala
+++ b/src/reflect/scala/reflect/internal/ClassfileConstants.scala
@@ -335,13 +335,8 @@ object ClassfileConstants {
abstract class FlagTranslation {
import Flags._
- private var isAnnotation = false
- private var isClass = false
- private def initFields(flags: Int) = {
- isAnnotation = (flags & JAVA_ACC_ANNOTATION) != 0
- isClass = false
- }
- private def translateFlag(jflag: Int): Long = (jflag: @switch) match {
+ private def isAnnotation(flags: Int): Boolean = (flags & JAVA_ACC_ANNOTATION) != 0
+ private def translateFlag(jflag: Int, isAnnotation: Boolean, isClass: Boolean): Long = (jflag: @switch) match {
case JAVA_ACC_PRIVATE => PRIVATE
case JAVA_ACC_PROTECTED => PROTECTED
case JAVA_ACC_FINAL => FINAL
@@ -351,31 +346,28 @@ object ClassfileConstants {
case JAVA_ACC_INTERFACE => if (isAnnotation) 0L else TRAIT | INTERFACE | ABSTRACT
case _ => 0L
}
- private def translateFlags(jflags: Int, baseFlags: Long): Long = {
+ private def translateFlags(jflags: Int, baseFlags: Long, isAnnotation: Boolean, isClass: Boolean): Long = {
+ def translateFlag0(jflags: Int): Long = translateFlag(jflags, isAnnotation, isClass)
var res: Long = JAVA | baseFlags
/** fast, elegant, maintainable, pick any two... */
- res |= translateFlag(jflags & JAVA_ACC_PRIVATE)
- res |= translateFlag(jflags & JAVA_ACC_PROTECTED)
- res |= translateFlag(jflags & JAVA_ACC_FINAL)
- res |= translateFlag(jflags & JAVA_ACC_SYNTHETIC)
- res |= translateFlag(jflags & JAVA_ACC_STATIC)
- res |= translateFlag(jflags & JAVA_ACC_ABSTRACT)
- res |= translateFlag(jflags & JAVA_ACC_INTERFACE)
+ res |= translateFlag0(jflags & JAVA_ACC_PRIVATE)
+ res |= translateFlag0(jflags & JAVA_ACC_PROTECTED)
+ res |= translateFlag0(jflags & JAVA_ACC_FINAL)
+ res |= translateFlag0(jflags & JAVA_ACC_SYNTHETIC)
+ res |= translateFlag0(jflags & JAVA_ACC_STATIC)
+ res |= translateFlag0(jflags & JAVA_ACC_ABSTRACT)
+ res |= translateFlag0(jflags & JAVA_ACC_INTERFACE)
res
}
def classFlags(jflags: Int): Long = {
- initFields(jflags)
- isClass = true
- translateFlags(jflags, 0)
+ translateFlags(jflags, 0, isAnnotation(jflags), isClass = true)
}
def fieldFlags(jflags: Int): Long = {
- initFields(jflags)
- translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) MUTABLE else 0)
+ translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) MUTABLE else 0 , isAnnotation(jflags), isClass = false)
}
def methodFlags(jflags: Int): Long = {
- initFields(jflags)
- translateFlags(jflags, if ((jflags & JAVA_ACC_BRIDGE) != 0) BRIDGE else 0)
+ translateFlags(jflags, if ((jflags & JAVA_ACC_BRIDGE) != 0) BRIDGE else 0, isAnnotation(jflags), isClass = false)
}
}
object FlagTranslation extends FlagTranslation { }