소스 검색

Fixes casting in constant folding in Painless (#61508)

The expression type wasn't being set to the target type after a constant fold on a ir cast node. This changes fixes that requirement.
Jack Conradson 5 년 전
부모
커밋
0ca776ed53

+ 1 - 0
modules/lang-painless/src/main/java/org/elasticsearch/painless/phase/DefaultConstantFoldingOptimizationPhase.java

@@ -667,6 +667,7 @@ public class DefaultConstantFoldingOptimizationPhase extends IRTreeBaseVisitor<C
             ConstantNode irConstantNode = (ConstantNode)irCastNode.getChildNode();
             irConstantNode.setConstant(
                     AnalyzerCaster.constCast(irCastNode.getLocation(), irConstantNode.getConstant(), irCastNode.getCast()));
+            irConstantNode.setExpressionType(irCastNode.getExpressionType());
             scope.accept(irConstantNode);
         }
     }

+ 14 - 1
modules/lang-painless/src/test/java/org/elasticsearch/painless/DefCastTests.java

@@ -485,7 +485,7 @@ public class DefCastTests extends ScriptTestCase {
         expectScriptThrows(ClassCastException.class, () -> exec("def d = Double.valueOf(0); Float b = d;"));
         expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); Float b = d;"));
     }
-    
+
     public void testdefToDoubleImplicit() {
         expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; Double b = d;"));
         expectScriptThrows(ClassCastException.class, () -> exec("def d = true; Double b = d;"));
@@ -684,6 +684,19 @@ public class DefCastTests extends ScriptTestCase {
         assertEquals("s", exec("def d = (char)'s'; String b = (String)d; b"));
     }
 
+    public void testConstFoldingDefCast() {
+        assertFalse((boolean)exec("def chr = 10; return (chr == (char)'x');"));
+        assertFalse((boolean)exec("def chr = 10; return (chr >= (char)'x');"));
+        assertTrue((boolean)exec("def chr = (char)10; return (chr <= (char)'x');"));
+        assertTrue((boolean)exec("def chr = 10; return (chr < (char)'x');"));
+        assertFalse((boolean)exec("def chr = (char)10; return (chr > (char)'x');"));
+        assertFalse((boolean)exec("def chr = 10L; return (chr > (char)'x');"));
+        assertFalse((boolean)exec("def chr = 10F; return (chr > (char)'x');"));
+        assertFalse((boolean)exec("def chr = 10D; return (chr > (char)'x');"));
+        assertFalse((boolean)exec("def chr = (char)10L; return (chr > (byte)10);"));
+        assertFalse((boolean)exec("def chr = (char)10L; return (chr > (double)(byte)(char)10);"));
+    }
+
     // TODO: remove this when the transition from Joda to Java datetimes is completed
     public void testdefToZonedDateTime() {
         assertEquals(0L, exec(