Skip to content

Commit ab8a223

Browse files
committed
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 af3daf6 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.
1 parent 8053c19 commit ab8a223

File tree

1 file changed

+14
-22
lines changed

1 file changed

+14
-22
lines changed

src/reflect/scala/reflect/internal/ClassfileConstants.scala

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -335,13 +335,8 @@ object ClassfileConstants {
335335
abstract class FlagTranslation {
336336
import Flags._
337337

338-
private var isAnnotation = false
339-
private var isClass = false
340-
private def initFields(flags: Int) = {
341-
isAnnotation = (flags & JAVA_ACC_ANNOTATION) != 0
342-
isClass = false
343-
}
344-
private def translateFlag(jflag: Int): Long = (jflag: @switch) match {
338+
private def isAnnotation(flags: Int): Boolean = (flags & JAVA_ACC_ANNOTATION) != 0
339+
private def translateFlag(jflag: Int, isAnnotation: Boolean, isClass: Boolean): Long = (jflag: @switch) match {
345340
case JAVA_ACC_PRIVATE => PRIVATE
346341
case JAVA_ACC_PROTECTED => PROTECTED
347342
case JAVA_ACC_FINAL => FINAL
@@ -351,31 +346,28 @@ object ClassfileConstants {
351346
case JAVA_ACC_INTERFACE => if (isAnnotation) 0L else TRAIT | INTERFACE | ABSTRACT
352347
case _ => 0L
353348
}
354-
private def translateFlags(jflags: Int, baseFlags: Long): Long = {
349+
private def translateFlags(jflags: Int, baseFlags: Long, isAnnotation: Boolean, isClass: Boolean): Long = {
350+
def translateFlag0(jflags: Int): Long = translateFlag(jflags, isAnnotation, isClass)
355351
var res: Long = JAVA | baseFlags
356352
/** fast, elegant, maintainable, pick any two... */
357-
res |= translateFlag(jflags & JAVA_ACC_PRIVATE)
358-
res |= translateFlag(jflags & JAVA_ACC_PROTECTED)
359-
res |= translateFlag(jflags & JAVA_ACC_FINAL)
360-
res |= translateFlag(jflags & JAVA_ACC_SYNTHETIC)
361-
res |= translateFlag(jflags & JAVA_ACC_STATIC)
362-
res |= translateFlag(jflags & JAVA_ACC_ABSTRACT)
363-
res |= translateFlag(jflags & JAVA_ACC_INTERFACE)
353+
res |= translateFlag0(jflags & JAVA_ACC_PRIVATE)
354+
res |= translateFlag0(jflags & JAVA_ACC_PROTECTED)
355+
res |= translateFlag0(jflags & JAVA_ACC_FINAL)
356+
res |= translateFlag0(jflags & JAVA_ACC_SYNTHETIC)
357+
res |= translateFlag0(jflags & JAVA_ACC_STATIC)
358+
res |= translateFlag0(jflags & JAVA_ACC_ABSTRACT)
359+
res |= translateFlag0(jflags & JAVA_ACC_INTERFACE)
364360
res
365361
}
366362

367363
def classFlags(jflags: Int): Long = {
368-
initFields(jflags)
369-
isClass = true
370-
translateFlags(jflags, 0)
364+
translateFlags(jflags, 0, isAnnotation(jflags), isClass = true)
371365
}
372366
def fieldFlags(jflags: Int): Long = {
373-
initFields(jflags)
374-
translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) MUTABLE else 0)
367+
translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) MUTABLE else 0 , isAnnotation(jflags), isClass = false)
375368
}
376369
def methodFlags(jflags: Int): Long = {
377-
initFields(jflags)
378-
translateFlags(jflags, if ((jflags & JAVA_ACC_BRIDGE) != 0) BRIDGE else 0)
370+
translateFlags(jflags, if ((jflags & JAVA_ACC_BRIDGE) != 0) BRIDGE else 0, isAnnotation(jflags), isClass = false)
379371
}
380372
}
381373
object FlagTranslation extends FlagTranslation { }

0 commit comments

Comments
 (0)