You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/09/30 11:04:11 UTC
[groovy] 01/03: Tweak GROOVY-9126: Eliminate more unreachable
bytecode
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 7001afedf510b31484128f91d04c0c966bce9967
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Sep 30 17:48:43 2020 +0800
Tweak GROOVY-9126: Eliminate more unreachable bytecode
---
.../groovy/classgen/AsmClassGenerator.java | 18 ++++++++++++
src/test/groovy/bugs/Groovy9126.groovy | 33 +++++++++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index 72024f0..9affbee 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -514,6 +514,9 @@ public class AsmClassGenerator extends ClassGenerator {
super.visitConstructorOrMethod(node, isConstructor);
controller.getCompileStack().clear();
+
+ if (checkIfLastStatementIsReturn(code)) return;
+
if (node.isVoidMethod()) {
mv.visitInsn(RETURN);
} else {
@@ -531,6 +534,21 @@ public class AsmClassGenerator extends ClassGenerator {
}
}
+ private boolean checkIfLastStatementIsReturn(Statement code) {
+ if (code instanceof BlockStatement) {
+ BlockStatement blockStatement = (BlockStatement) code;
+ List<Statement> statementList = blockStatement.getStatements();
+ int statementCnt = statementList.size();
+ if (statementCnt > 0) {
+ Statement lastStatement = statementList.get(statementCnt - 1);
+ if (lastStatement instanceof ReturnStatement) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private void visitAnnotationDefaultExpression(final AnnotationVisitor av, final ClassNode type, final Expression exp) {
if (exp instanceof ClosureExpression) {
ClassNode closureClass = controller.getClosureWriter().getOrAddClosureClass((ClosureExpression) exp, ACC_PUBLIC);
diff --git a/src/test/groovy/bugs/Groovy9126.groovy b/src/test/groovy/bugs/Groovy9126.groovy
index 3df9633..69ec5ff 100644
--- a/src/test/groovy/bugs/Groovy9126.groovy
+++ b/src/test/groovy/bugs/Groovy9126.groovy
@@ -45,7 +45,38 @@ final class Groovy9126 extends AbstractBytecodeTestCase {
'IMUL',
'IRETURN',
'L1',
- 'FRAME FULL [] [java/lang/Throwable]']
+ 'LOCALVARIABLE this Lscript; L0 L1 0']
+ )
+ }
+
+ @Test
+ void testUnreachableBytecode2() {
+ def bytecode = compile([method:'nonVoidMethod'],'''
+ @groovy.transform.CompileStatic
+ def nonVoidMethod() {
+ println 123
+ 567
+ }
+ ''')
+
+ assert bytecode.hasStrictSequence(
+ ['public nonVoidMethod()Ljava/lang/Object;',
+ 'L0',
+ 'LINENUMBER 4 L0',
+ 'ALOAD 0',
+ 'CHECKCAST script',
+ 'BIPUSH 123',
+ 'INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;',
+ 'INVOKEVIRTUAL script.println (Ljava/lang/Object;)V',
+ 'ACONST_NULL',
+ 'POP',
+ 'L1',
+ 'LINENUMBER 5 L1',
+ 'SIPUSH 567',
+ 'INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;',
+ 'ARETURN',
+ 'L2',
+ 'LOCALVARIABLE this Lscript; L0 L2 0']
)
}
}