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) {
}
'''
}
}