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 2021/11/26 21:04:01 UTC
[groovy] branch master updated: GROOVY-8693: SC - override default method: no `super.m()` stack overflow
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 538374a GROOVY-8693: SC - override default method: no `super.m()` stack overflow
538374a is described below
commit 538374a1799947912496bf3a9aa8590cf5e38a75
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Nov 26 14:44:25 2021 -0600
GROOVY-8693: SC - override default method: no `super.m()` stack overflow
---
.../codehaus/groovy/classgen/asm/InvocationWriter.java | 10 ++++++----
.../groovy/classgen/asm/sc/BugsStaticCompileTest.groovy | 16 ++++++++++++++++
2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
index c7786c5..c8af4b5 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
@@ -168,16 +168,18 @@ public class InvocationWriter {
int opcode;
if (target.isStatic()) {
opcode = INVOKESTATIC;
+ } else if (isSuperExpression(receiver)) {
+ opcode = INVOKESPECIAL;
} else if (declaringClass.isInterface()) {
opcode = INVOKEINTERFACE;
- } else if (target.isPrivate() || isSuperExpression(receiver)) {
- opcode = INVOKESPECIAL;
} else {
opcode = INVOKEVIRTUAL;
}
ClassNode ownerClass = declaringClass;
- if (opcode == INVOKEVIRTUAL && isObjectType(declaringClass)) {
+ if (opcode == INVOKESPECIAL) {
+ ownerClass = receiverType; // GROOVY-8693
+ } else if (opcode == INVOKEVIRTUAL && isObjectType(declaringClass)) {
// avoid using a narrowed type if the method is defined on Object, because it can interfere
// with delegate type inference in static compilation mode and trigger a ClassCastException
} else if (opcode == INVOKEVIRTUAL
@@ -190,7 +192,7 @@ public class InvocationWriter {
if (!receiverType.equals(operandStack.getTopOperand())) {
mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(ownerClass));
}
- } else if (opcode != INVOKESPECIAL && (declaringClass.getModifiers() & (ACC_FINAL | ACC_PUBLIC)) == 0 && !receiverType.equals(declaringClass)
+ } else if ((declaringClass.getModifiers() & (ACC_FINAL | ACC_PUBLIC)) == 0 && !receiverType.equals(declaringClass)
&& (declaringClass.isInterface() ? receiverType.implementsInterface(declaringClass) : receiverType.isDerivedFrom(declaringClass))) {
// GROOVY-6962, GROOVY-9955, GROOVY-10380: method declared by inaccessible class or interface
if (declaringClass.isInterface() && !receiverType.isInterface()) opcode = INVOKEVIRTUAL;
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy
index 5576b16..77abc66 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy
@@ -1524,4 +1524,20 @@ println someInt
test()
'''
}
+
+ // GROOVY-8693
+ void testInvokeDefaultMethodFromPackagePrivateInterface2() {
+ assertScript '''
+ class C extends groovy.transform.stc.Groovy10380 {
+ @Override String m() {
+ super.m() // default method
+ }
+ void test() {
+ String result = this.m()
+ assert result == 'works'
+ }
+ }
+ new C().test()
+ '''
+ }
}