GROOVY-5980: Finally executes twice on NPE while casting method result
diff --git a/src/main/org/codehaus/groovy/classgen/asm/StatementWriter.java b/src/main/org/codehaus/groovy/classgen/asm/StatementWriter.java
index 5443167..018a225 100644
--- a/src/main/org/codehaus/groovy/classgen/asm/StatementWriter.java
+++ b/src/main/org/codehaus/groovy/classgen/asm/StatementWriter.java
@@ -575,16 +575,16 @@
Expression expression = statement.getExpression();
expression.visit(controller.getAcg());
-
+
+ operandStack.doGroovyCast(returnType);
+
if (controller.getCompileStack().hasBlockRecorder()) {
ClassNode type = operandStack.getTopOperand();
- // value is always saved in boxed form, so no need to have a special load routine here
- int returnValueIdx = controller.getCompileStack().defineTemporaryVariable("returnValue", type, true);
+ int returnValueIdx = controller.getCompileStack().defineTemporaryVariable("returnValue", returnType, true);
controller.getCompileStack().applyBlockRecorder();
operandStack.load(type, returnValueIdx);
}
-
- operandStack.doGroovyCast(returnType);
+
BytecodeHelper.doReturn(mv, returnType);
operandStack.remove(1);
}
diff --git a/src/test/groovy/lang/SyntheticReturnTest.groovy b/src/test/groovy/lang/SyntheticReturnTest.groovy
index 7c83ecb..e1865e9 100644
--- a/src/test/groovy/lang/SyntheticReturnTest.groovy
+++ b/src/test/groovy/lang/SyntheticReturnTest.groovy
@@ -1,6 +1,43 @@
package groovy.lang
class SyntheticReturnTest extends GroovyShellTestCase{
+
+ // GROOVY-5980
+ void testImplicitReturnWithFinallyBlockAndCastException() {
+ assertEquals( 'test', evaluate("""
+ s = ''
+ int f() {
+ try { null } finally { s += 'test' }
+ }
+ try { f() } catch (ex) {}
+ s
+ """))
+ }
+
+ void testImplicitReturnWithFinallyBlockMultipleStmtsAndCastException() {
+ assertEquals( 'test', evaluate("""
+ i = 0
+ s = ''
+ int f() {
+ try { def t = 41 + 1; i = t; null } finally { assert i == 42; s += 'test' }
+ }
+ try { f() } catch (ex) {}
+ s
+ """))
+ }
+
+ void testImplicitReturnWithFinallyBlockAndTypeCast() {
+ assertEquals( '42', evaluate("""
+ s = ''
+ String f() {
+ try { 42 } finally { s += 'test' }
+ }
+ def result = f()
+ assert s == 'test'
+ result
+ """))
+ }
+
void testExpt () {
assertEquals( 5, evaluate("""
5