Skip to content
This repository
Browse code

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.
  • Loading branch information...
commit ab8a223c6c01c1a725c9892c04952f6451aedf0d 1 parent 8053c19
Jason Zaugg retronym authored

Showing 1 changed file with 14 additions and 22 deletions. Show diff stats Hide diff stats

  1. +14 22 src/reflect/scala/reflect/internal/ClassfileConstants.scala
36 src/reflect/scala/reflect/internal/ClassfileConstants.scala
@@ -335,13 +335,8 @@ object ClassfileConstants {
335 335 abstract class FlagTranslation {
336 336 import Flags._
337 337
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 {
345 340 case JAVA_ACC_PRIVATE => PRIVATE
346 341 case JAVA_ACC_PROTECTED => PROTECTED
347 342 case JAVA_ACC_FINAL => FINAL
@@ -351,31 +346,28 @@ object ClassfileConstants {
351 346 case JAVA_ACC_INTERFACE => if (isAnnotation) 0L else TRAIT | INTERFACE | ABSTRACT
352 347 case _ => 0L
353 348 }
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)
355 351 var res: Long = JAVA | baseFlags
356 352 /** 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)
364 360 res
365 361 }
366 362
367 363 def classFlags(jflags: Int): Long = {
368   - initFields(jflags)
369   - isClass = true
370   - translateFlags(jflags, 0)
  364 + translateFlags(jflags, 0, isAnnotation(jflags), isClass = true)
371 365 }
372 366 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)
375 368 }
376 369 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)
379 371 }
380 372 }
381 373 object FlagTranslation extends FlagTranslation { }

0 comments on commit ab8a223

Please sign in to comment.
Something went wrong with that request. Please try again.