You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2019/11/25 18:24:15 UTC
[groovy] branch master updated: GROOVY-8648: fix ASM error for this
or super attribute expression on LHS
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 06da956 GROOVY-8648: fix ASM error for this or super attribute expression on LHS
06da956 is described below
commit 06da9561f0a274ce71c7a1b669841bc70c61766d
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Nov 25 11:55:01 2019 -0600
GROOVY-8648: fix ASM error for this or super attribute expression on LHS
java.lang.NegativeArraySizeException
at groovyjarjarasm.asm.Frame.merge(Frame.java:1222)
at groovyjarjarasm.asm.MethodWriter.computeAllFrames(MethodWriter.java:1610)
at groovyjarjarasm.asm.MethodWriter.visitMaxs(MethodWriter.java:1546)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitConstructorOrMethod(AsmClassGenerator.java:410)
---
.../groovy/classgen/AsmClassGenerator.java | 36 ++++++++--------
src/test/groovy/bugs/Groovy8648.groovy | 49 ++++++++++++++++++++++
2 files changed, 68 insertions(+), 17 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index 2c688f8..3e50687 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -1147,36 +1147,41 @@ public class AsmClassGenerator extends ClassGenerator {
@Override
public void visitAttributeExpression(AttributeExpression expression) {
Expression objectExpression = expression.getObjectExpression();
- ClassNode classNode = controller.getClassNode();
+ OperandStack operandStack = controller.getOperandStack();
+ int mark = operandStack.getStackLength() - 1;
+ boolean visited = false;
+
// TODO: checking for isThisOrSuper is enough for AttributeExpression, but if this is moved into
// visitAttributeOrProperty to handle attributes and properties equally, then the extended check should be done
if (isThisOrSuper(objectExpression)) {
// let's use the field expression if it's available
String name = expression.getPropertyAsString();
if (name != null) {
+ ClassNode classNode = controller.getClassNode();
FieldNode field = getDeclaredFieldOfCurrentClassOrAccessibleFieldOfSuper(classNode, classNode, name, isSuperExpression(objectExpression));
if (field != null) {
FieldExpression fldExp = new FieldExpression(field);
fldExp.setSourcePosition(expression.getProperty());
visitFieldExpression(fldExp);
- return;
+ visited = true;
}
}
}
- MethodCallerMultiAdapter adapter;
- OperandStack operandStack = controller.getOperandStack();
- int mark = operandStack.getStackLength() - 1;
- if (controller.getCompileStack().isLHS()) {
- adapter = setField;
- if (isGroovyObject(objectExpression)) adapter = setGroovyObjectField;
- if (usesSuper(expression)) adapter = setFieldOnSuper;
- } else {
- adapter = getField;
- if (isGroovyObject(objectExpression)) adapter = getGroovyObjectField;
- if (usesSuper(expression)) adapter = getFieldOnSuper;
+ if (!visited) {
+ MethodCallerMultiAdapter adapter;
+ if (controller.getCompileStack().isLHS()) {
+ adapter = setField;
+ if (isGroovyObject(objectExpression)) adapter = setGroovyObjectField;
+ if (usesSuper(expression)) adapter = setFieldOnSuper;
+ } else {
+ adapter = getField;
+ if (isGroovyObject(objectExpression)) adapter = getGroovyObjectField;
+ if (usesSuper(expression)) adapter = getFieldOnSuper;
+ }
+ visitAttributeOrProperty(expression, adapter);
}
- visitAttributeOrProperty(expression, adapter);
+
if (controller.getCompileStack().isLHS()) {
operandStack.remove(operandStack.getStackLength() - mark);
} else {
@@ -1210,9 +1215,6 @@ public class AsmClassGenerator extends ClassGenerator {
loadInstanceField(expression);
}
}
- if (!controller.getCompileStack().isLHS()) {
- controller.getAssertionWriter().record(expression);
- }
}
public void loadStaticField(FieldExpression fldExp) {
diff --git a/src/test/groovy/bugs/Groovy8648.groovy b/src/test/groovy/bugs/Groovy8648.groovy
new file mode 100644
index 0000000..2687c2a
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy8648.groovy
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package groovy.bugs
+
+import groovy.transform.CompileStatic
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+@CompileStatic
+final class Groovy8648 {
+
+ @Test
+ void testDirectFieldAccessOnLHS() {
+ assertScript '''
+ class Account {
+ private int balance = 0
+ int getBalance() {
+ return balance
+ }
+ void deposit(int amount) {
+ assert amount > 0
+ this.@balance += amount // ASM error for LHS attribute expression
+ }
+ }
+
+ new Account().with {
+ deposit(42)
+ assert balance == 42
+ }
+ '''
+ }
+}