This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Compiler bug with -optimise and final classes with var constructors

No replies
ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
The following program gives incorrect results when compiled with the -optimise flag under 2.7.4, 2.7.5, and last night's nightly build of 2.8.0:

Code:
final class V(var x:Int , var y:Int) {
  def +=(ax:Int,ay:Int) { x += ax ; y += ay }
}
 
final class U {
  var x:Int = 0
  var y:Int = 0
  def +=(ax:Int,ay:Int) { x += ax ; y += ay }
}

object Fail {
  def main(args:Array[String]) {
    val vm = new V(0,0)
    vm += (5,10)
    val um = new U
    um += (5,10) 
    var i = 0    
    while (i<1) {     
      um += ( i , 1-i )
      i += 1
    }

    println("Answers are " + (vm.x+vm.y) + " and " + (um.x+um.y))
  }

  
Good output:
~/code/scala$ rm *.class ; ~/pkg/scala-2.8.0.r18509-b20090819020207/bin/scalac Fail.scala
~/code/scala$ java -cp ~/pkg/scala-2.8.0.r18509-b20090819020207/lib/scala-library.jar:. Fail
Answers are 15 and 16
~/code/scala$

Bad optimized output:
~/code/scala$ rm *.class ; ~/pkg/scala-2.8.0.r18509-b20090819020207/bin/scalac -optimise Fail.scala
~/code/scala$ java -cp ~/pkg/scala-2.8.0.r18509-b20090819020207/lib/scala-library.jar:. Fail
Answers are 0 and 16
~/code/scala$


Somehow, even though um of type U is being operated on in the loop, it wipes out the value in vm.

Removing the loop fixes the problem.  Having V non-final fixes the problem.  Moving the vars inside the body of the class fixes the problem (as U demonstrates).  Making vm a var does *not* fix the problem.  Making vm a tuple with the vector as vm._1 fixes the problem.  Putting vm into another tuple right after vm += (5,10) fixes the problem *if* you read from the tuple for the answer, but *not* if you read from vm itself for the answer.  Simply setting another val equal to vm (i.e. creating a reference) does not fix the problem.  In more complicated programs, this bug can manifest intermittently--multiple compiles of the same code will sometimes show this bug and sometimes not.

Has anyone else noticed anything like this?  I suppose the proper thing to do is to submit this to the ScalaTrac database.

  --Rex

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland