@@ -9,7 +9,7 @@ import asm.tree._
9
9
10
10
import scala .tools .asm .Opcodes
11
11
import scala .jdk .CollectionConverters ._
12
-
12
+ import Opcodes . _
13
13
14
14
class TestBCode extends DottyBytecodeTest {
15
15
import ASMConverters ._
@@ -786,6 +786,42 @@ class TestBCode extends DottyBytecodeTest {
786
786
}
787
787
}
788
788
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
+
789
825
@ Test
790
826
def invocationReceivers (): Unit = {
791
827
import Opcodes ._
0 commit comments