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 2022/07/29 19:48:33 UTC

[groovy] branch master updated: GROOVY-10711: SC: if type declares `asBoolean()`, no `null` optimization

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 cebc9188cc GROOVY-10711: SC: if type declares `asBoolean()`, no `null` optimization
cebc9188cc is described below

commit cebc9188cc5734b161e7fc346c0ac67b87126d0d
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Jul 29 14:45:49 2022 -0500

    GROOVY-10711: SC: if type declares `asBoolean()`, no `null` optimization
---
 .../transformers/BooleanExpressionTransformer.java |  9 ++++---
 ...StaticCompileNullCompareOptimizationTest.groovy | 28 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/sc/transformers/BooleanExpressionTransformer.java b/src/main/java/org/codehaus/groovy/transform/sc/transformers/BooleanExpressionTransformer.java
index 2bfaa50151..988dfc590e 100644
--- a/src/main/java/org/codehaus/groovy/transform/sc/transformers/BooleanExpressionTransformer.java
+++ b/src/main/java/org/codehaus/groovy/transform/sc/transformers/BooleanExpressionTransformer.java
@@ -22,6 +22,7 @@ import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.GroovyCodeVisitor;
 import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.expr.BinaryExpression;
 import org.codehaus.groovy.ast.expr.BooleanExpression;
 import org.codehaus.groovy.ast.expr.Expression;
@@ -163,14 +164,16 @@ class BooleanExpressionTransformer {
 
         /**
          * Inline an "expr != null" check instead of boolean conversion iff:
-         * (1) the class doesn't define an asBoolean method (already tested)
-         * (2) no subclass defines an asBoolean method
+         * (1) the class doesn't define an {@code asBoolean()} method
+         * (2) no subclass defines an {@code asBoolean()} method
          * For (2), check that we are in one of these cases:
          *   (a) a final class
          *   (b) an effectively-final inner class
          */
         private static boolean replaceAsBooleanWithCompareToNull(final ClassNode type, final ClassLoader dgmProvider) {
-            if (Modifier.isFinal(type.getModifiers()) || isEffectivelyFinal(type)) {
+            if (type.getMethod("asBoolean", Parameter.EMPTY_ARRAY) != null) {
+                // GROOVY-10711
+            } else if (Modifier.isFinal(type.getModifiers()) || isEffectivelyFinal(type)) {
                 List<MethodNode> asBoolean = findDGMMethodsByNameAndArguments(dgmProvider, type, "asBoolean", ClassNode.EMPTY_ARRAY);
                 if (asBoolean.size() == 1) {
                     MethodNode theAsBoolean = asBoolean.get(0);
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileNullCompareOptimizationTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileNullCompareOptimizationTest.groovy
index 8adae6e991..d43e44c925 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileNullCompareOptimizationTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileNullCompareOptimizationTest.groovy
@@ -295,6 +295,34 @@ final class StaticCompileNullCompareOptimizationTest extends AbstractBytecodeTes
         ])
     }
 
+    // GROOVY-10711
+    void testNoGroovyTruthOptimizationIfProvidesAsBoolean() {
+        def bytecode = compile(method:'m', '''
+            @groovy.transform.CompileStatic
+            @groovy.transform.Immutable
+            class C {
+                boolean asBoolean() {
+                }
+            }
+
+            @groovy.transform.CompileStatic
+            void m(C x) {
+                if (!x) {
+                }
+            }
+        ''')
+        assert bytecode.hasSequence([
+            'ALOAD 1',
+            'DUP',
+            'IFNONNULL L1',
+            'POP',
+            'ICONST_0',
+            'GOTO L2',
+            'L1',
+            'INVOKEDYNAMIC cast(LC;)Z'
+        ])
+    }
+
     void testCompare() {
         assertScript '''
             class Pogo {