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