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/01/31 18:55:31 UTC

[groovy] 01/06: GROOVY-9336: integer target type for shift RHS in constant initializer

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 8bc4644aa5038ec6496193c7612f299bde552084
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Jan 11 12:23:47 2020 -0600

    GROOVY-9336: integer target type for shift RHS in constant initializer
    
    (cherry picked from commit b133efc8efbeb24da4601bdfd12bf5a008032d72)
    
    Conflicts:
    	src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java
---
 .../apache/groovy/ast/tools/ExpressionUtils.java   | 35 +++++++-----------
 src/test/groovy/bugs/Groovy9336.groovy             | 42 ++++++++++++++++++++++
 2 files changed, 55 insertions(+), 22 deletions(-)

diff --git a/src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java b/src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java
index 8cec61a..2321404 100644
--- a/src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java
@@ -33,7 +33,7 @@ import org.codehaus.groovy.runtime.typehandling.NumberMath;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.ArrayList;
+import java.util.Arrays;
 
 import static org.codehaus.groovy.syntax.Types.BITWISE_AND;
 import static org.codehaus.groovy.syntax.Types.BITWISE_OR;
@@ -48,25 +48,16 @@ import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT;
 import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT_UNSIGNED;
 
 public final class ExpressionUtils {
-    private static ArrayList<Integer> handledTypes = new ArrayList<Integer>();
 
     private ExpressionUtils() {
-
     }
 
-    static {
-        handledTypes.add(PLUS);
-        handledTypes.add(MINUS);
-        handledTypes.add(MULTIPLY);
-        handledTypes.add(DIVIDE);
-        handledTypes.add(LEFT_SHIFT);
-        handledTypes.add(RIGHT_SHIFT);
-        handledTypes.add(RIGHT_SHIFT_UNSIGNED);
-        handledTypes.add(BITWISE_OR);
-        handledTypes.add(BITWISE_AND);
-        handledTypes.add(BITWISE_XOR);
-        handledTypes.add(POWER);
-    }
+    // NOTE: values are sorted in ascending order
+    private static final int[] HANDLED_TYPES = {
+        PLUS, MINUS, MULTIPLY, DIVIDE, POWER,
+        LEFT_SHIFT, RIGHT_SHIFT, RIGHT_SHIFT_UNSIGNED,
+        BITWISE_OR, BITWISE_AND, BITWISE_XOR,
+    };
 
     /**
      * Turns expressions of the form ConstantExpression(40) + ConstantExpression(2)
@@ -92,9 +83,10 @@ public final class ExpressionUtils {
             }
         } else if (isNumberOrArrayOfNumber(wrapperType, false)) {
             int type = be.getOperation().getType();
-            if (handledTypes.contains(type)) {
+            if (Arrays.binarySearch(HANDLED_TYPES, type) >= 0) {
+                boolean isShift = (type >= LEFT_SHIFT && type <= RIGHT_SHIFT_UNSIGNED);
                 Expression leftX = transformInlineConstants(be.getLeftExpression(), targetType);
-                Expression rightX = transformInlineConstants(be.getRightExpression(), targetType);
+                Expression rightX = transformInlineConstants(be.getRightExpression(), isShift ? ClassHelper.int_TYPE : targetType);
                 if (leftX instanceof ConstantExpression && rightX instanceof ConstantExpression) {
                     Number left = safeNumber((ConstantExpression) leftX);
                     Number right = safeNumber((ConstantExpression) rightX);
@@ -342,10 +334,9 @@ public final class ExpressionUtils {
     }
 
     private static Expression findConstant(FieldNode fn) {
-        if (fn != null && !fn.isEnum() && fn.isStatic() && fn.isFinal()) {
-            if (fn.getInitialValueExpression() instanceof ConstantExpression) {
-                return fn.getInitialValueExpression();
-            }
+        if (fn != null && !fn.isEnum() && fn.isStatic() && fn.isFinal()
+                && fn.getInitialValueExpression() instanceof ConstantExpression) {
+            return fn.getInitialValueExpression();
         }
         return null;
     }
diff --git a/src/test/groovy/bugs/Groovy9336.groovy b/src/test/groovy/bugs/Groovy9336.groovy
new file mode 100644
index 0000000..5aa837e
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9336.groovy
@@ -0,0 +1,42 @@
+/*
+ *  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 Groovy9336 {
+
+    @Test
+    void testShiftInStaticFieldInitializer() {
+        assertScript '''
+            class Groovy9336 {
+                // initializer evaluated like (2 as double) << ((16 - 1) as double); need int on RHS
+                public static double N = 2 << 16 - 1
+
+                static main(args) {
+                    assert N == 65536.0d
+                }
+            }
+        '''
+    }
+}