Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

return inside try + pattern-match inside finally causes VerifyError #7407

Closed
scabug opened this issue Apr 23, 2013 · 5 comments
Closed

return inside try + pattern-match inside finally causes VerifyError #7407

scabug opened this issue Apr 23, 2013 · 5 comments
Assignees
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Apr 23, 2013

When upgrading to 2.9.2. to 2.10.1, ran into this.
Minimal test case:

def foo: String = try return "Hello" finally 10 match {case x => ()}

throws

java.lang.VerifyError: (class: , method: foo signature: ()Ljava/lang/String;) Inconsistent stack height 0 != 1

when accessed.

Seems to be the combination of return in the try and the pattern match in the finally that does it.

Looks like James Iry blogged about something related, recently:
http://james-iry.blogspot.com/2013/01/scala-trycatch-lifting-proposal.html

@scabug
Copy link
Author

scabug commented Apr 23, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7407?orig=1
Reporter: Leif Warner (pdxleif)
Affected Versions: 2.10.1

@scabug
Copy link
Author

scabug commented Apr 24, 2013

@magarciaEPFL said:
A variation of the minimized snippet, which also exercises the "non-early-return" control-flow path:

object Test {

  def main(args: Array[String]) {
    println(foo(true))
    println(foo(false))
  }

  def foo(b: Boolean): String = {
    try {
      if(b)
        return "Hello"
      else
        "abc"
    } finally {
      10 match {case x => ()}
    }
  }

}

The problem does not surface in the new backend (ok, after fixing a typo) because a more structured approach is followed to emit try-catch-finally,

magarciaEPFL/scala@master...GenRefactored27

@scabug
Copy link
Author

scabug commented Jul 8, 2013

Leif Warner (pdxleif) said:
OpenJDK7u40 seems to give more detailed info on these VerifyErrors, a la:

java.lang.VerifyError: Instruction type does not match stack map
Exception Details:
  Location:
    .foo()Ljava/lang/String; @20: aload_1
  Reason:
    Current frame's stack size doesn't match stackmap.
  Current Frame:
    bci: @20
    flags: { }
    locals: { '', 'java/lang/Throwable', integer, 'scala/runtime/BoxedUnit' }
    stack: { }
  Stackmap Frame:
    bci: @20
    flags: { }
    locals: { '', top, integer, 'scala/runtime/BoxedUnit' }
    stack: { 'java/lang/String' }
  Bytecode:
    0000000: 1210 100a 3db2 0016 4ea7 000b 4c10 0a3d
    0000010: b200 164e 2bbf                         
  Exception Handler Table:
    bci [0, 2] => handler: 12
  Stackmap Table:
    same_locals_1_stack_item_frame(@12,Object[#25])
    full_frame(@20,{Object[#2],Top,Integer,Object[#18]},{Object[#27]})

	at .<init>(<console>:7)
	at .<clinit>(<console>)
	at $print(<console>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:734)

@scabug
Copy link
Author

scabug commented Oct 20, 2014

@lrytz said:
As Miguel says, works in the new backend.

Test case was added in 2a659cf0, updated in scala/scala#4068

@scabug
Copy link
Author

scabug commented Nov 18, 2014

@retronym said:
Fixed in 2.11.5 under -Ybackend:GenBCode, which will be non-experimental and enabled by default in the 2.12 series soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants