This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 9b4ec311df GROOVY-9805: checkcast to keep local variable type in the 
stackmap frame
9b4ec311df is described below

commit 9b4ec311df38c915fdaa36f8b5c37585cc90762c
Author: Eric Milles <[email protected]>
AuthorDate: Sat Feb 14 23:57:22 2026 -0600

    GROOVY-9805: checkcast to keep local variable type in the stackmap frame
---
 .../codehaus/groovy/classgen/asm/OperandStack.java | 20 +++++++++------
 src/test/groovy/bugs/Groovy9805.groovy             | 30 ++++++++++++++++++----
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java 
b/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java
index 1b37d05cc4..734d3afe97 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java
@@ -612,22 +612,26 @@ public class OperandStack {
 
     public void storeVar(final BytecodeVariable variable) {
         MethodVisitor mv = controller.getMethodVisitor();
-        int idx = variable.getIndex();
         ClassNode type = variable.getType();
-        // value is on stack
+
+        doGroovyCast(type);
         if (variable.isHolder()) {
-            doGroovyCast(type);
             box();
-            mv.visitVarInsn(ALOAD, idx);
+            mv.visitVarInsn(ALOAD, variable.getIndex());
             mv.visitTypeInsn(CHECKCAST, "groovy/lang/Reference");
             mv.visitInsn(SWAP);
             mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Reference", "set", 
"(Ljava/lang/Object;)V", false);
         } else {
-            doGroovyCast(type);
-            BytecodeHelper.store(mv, type, idx);
+            if (!getTopOperand().equals(type) && 
controller.getCompileStack().hasBlockRecorder()) {
+                // GROOVY-9805: force type in the stackmap
+                mv.visitTypeInsn(CHECKCAST, type.isArray()
+                        ? BytecodeHelper.getTypeDescription(type)
+                        : BytecodeHelper.getClassInternalName(type.getName()));
+            }
+            BytecodeHelper.store(mv, type, variable.getIndex());
         }
-        // remove RHS value from operand stack
-        remove(1);
+
+        remove(1); // remove RHS value from operand stack
     }
 
     public void load(final ClassNode type, final int idx) {
diff --git a/src/test/groovy/bugs/Groovy9805.groovy 
b/src/test/groovy/bugs/Groovy9805.groovy
index b59edbaed6..9f18c19b7c 100644
--- a/src/test/groovy/bugs/Groovy9805.groovy
+++ b/src/test/groovy/bugs/Groovy9805.groovy
@@ -18,17 +18,37 @@
  */
 package bugs
 
-import groovy.test.NotYetImplemented
 import org.junit.jupiter.api.Test
 
 import static groovy.test.GroovyAssert.assertScript
 
 final class Groovy9805 {
-    @NotYetImplemented @Test
-    void testNoVerifyErrorForStatementsOnSameLine() {
+
+    @Test
+    void testSameLineAssignments1() {
+        assertScript '''
+            Object x; x = System.nanoTime(); x = ""
+        '''
+    }
+
+    @Test
+    void testSameLineAssignments2() {
+        assertScript '''
+            Object x; try { x = System.nanoTime(); x = "x value" } catch (e) { 
}
+        '''
+    }
+
+    @Test
+    void testSameLineAssignments3() {
+        assertScript '''
+            Object[] x; try { x = new Long[0]; x = new String[0] } catch (e) { 
}
+        '''
+    }
+
+    @Test
+    void testSameLineAssignments4() {
         assertScript '''
-            def x; try { x = System.nanoTime(); x = "ok" } catch (e) { }
-            //                                 ^ adding a label here in 
classgen is possible fix
+            CharSequence x; try { x = new StringBuffer(); x = "" } catch (e) { 
}
         '''
     }
 }

Reply via email to