diff options
| -rw-r--r-- | chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java | 4 | ||||
| -rw-r--r-- | chapter14/src/test/java/com/seaofnodes/simple/Chapter14Test.java | 18 |
2 files changed, 20 insertions, 2 deletions
diff --git a/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java index 8a2c9406..8ba45d26 100644 --- a/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -22,7 +22,9 @@ public class MinusNode extends Node { public Type compute() { if( in(1)._type instanceof TypeInteger i0 ) { if( i0.isHigh() ) return TypeInteger.TOP; - return i0==TypeInteger.BOT ? TypeInteger.BOT : TypeInteger.make(-i0._max,-i0._min); + // Catch overflow wrapping on `-Long.MIN_VALUE` + if( i0 == TypeInteger.BOT || i0._min == Long.MIN_VALUE ) return TypeInteger.BOT; + return TypeInteger.make(-i0._max,-i0._min); } return TypeInteger.TOP.meet(in(1)._type); } diff --git a/chapter14/src/test/java/com/seaofnodes/simple/Chapter14Test.java b/chapter14/src/test/java/com/seaofnodes/simple/Chapter14Test.java index 5f7cf954..5a62b905 100644 --- a/chapter14/src/test/java/com/seaofnodes/simple/Chapter14Test.java +++ b/chapter14/src/test/java/com/seaofnodes/simple/Chapter14Test.java @@ -15,7 +15,7 @@ public class Chapter14Test { """ return 3.14; """); - StopNode stop = parser.parse(false).iterate(false); + StopNode stop = parser.parse(false).iterate(true); assertEquals("return 3.14;", stop.toString()); assertEquals(3.14, Evaluator.evaluate(stop, 0)); } @@ -142,6 +142,22 @@ return c; // } @Test + public void testWrapMinus() { + Parser parser = new Parser( +""" +int MAX = 9223372036854775807; //0x7FFFFFFFFFFFFFFF; +int i = (arg&MAX) + -MAX + -1; // Basically (e0) + Long.MIN_VALUE +int j = -i; // Negating Long.MIN_VALUE wraps, cannot constant fold +if (arg) j = 1; +return j; +"""); + StopNode stop = parser.parse(false).iterate(true); + assertEquals("return Phi(Region28,1,(-((arg&9223372036854775807)+-9223372036854775808)));", stop.toString()); + assertEquals(-9223372036854775808L, Evaluator.evaluate(stop, 0)); + assertEquals(1, Evaluator.evaluate(stop, 1)); + } + + @Test public void testOr() { Parser parser = new Parser( """ |
