@@ -9,7 +9,7 @@ import asm.tree._
99
1010import scala .tools .asm .Opcodes
1111import scala .jdk .CollectionConverters ._
12-
12+ import Opcodes . _
1313
1414class TestBCode extends DottyBytecodeTest {
1515 import ASMConverters ._
@@ -786,6 +786,42 @@ class TestBCode extends DottyBytecodeTest {
786786 }
787787 }
788788
789+
790+ @ Test // wrong local variable table for methods containing while loops
791+ def t9179 (): Unit = {
792+ val code =
793+ """ class C {
794+ | def t(): Unit = {
795+ | var x = ""
796+ | while (x != null) {
797+ | foo()
798+ | x = null
799+ | }
800+ | bar()
801+ | }
802+ | def foo(): Unit = ()
803+ | def bar(): Unit = ()
804+ |}
805+ """ .stripMargin
806+ checkBCode(code) { dir =>
807+ val c = loadClassNode(dir.lookupName(" C.class" , directory = false ).input, skipDebugInfo = false )
808+ val t = getMethod(c, " t" )
809+ val instructions = instructionsFromMethod(t)
810+ val isFrameLine = (x : Instruction ) => x.isInstanceOf [FrameEntry ] || x.isInstanceOf [LineNumber ]
811+ // TODO: The same test in scalac uses different labels because their LineNumberTable isn't the same as ours,
812+ // this should be investigated.
813+ assertSameCode(instructions.filterNot(isFrameLine), List (
814+ Label (0 ), Ldc (LDC , " " ), VarOp (ASTORE , 1 ),
815+ Label (5 ), VarOp (ALOAD , 1 ), Jump (IFNULL , Label (19 )),
816+ Label (10 ), VarOp (ALOAD , 0 ), Invoke (INVOKEVIRTUAL , " C" , " foo" , " ()V" , false ), Label (14 ), Op (ACONST_NULL ), VarOp (ASTORE , 1 ), Jump (GOTO , Label (5 )),
817+ Label (19 ), VarOp (ALOAD , 0 ), Invoke (INVOKEVIRTUAL , " C" , " bar" , " ()V" , false ), Label (24 ), Op (RETURN ), Label (26 )))
818+ val labels = instructions collect { case l : Label => l }
819+ val x = convertMethod(t).localVars.find(_.name == " x" ).get
820+ assertEquals(x.start, labels(1 ))
821+ assertEquals(x.end, labels(5 ))
822+ }
823+ }
824+
789825 @ Test
790826 def invocationReceivers (): Unit = {
791827 import Opcodes ._
0 commit comments