summaryrefslogtreecommitdiff
path: root/chapter25/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'chapter25/src/test')
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter10Test.java15
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java14
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter18Test.java16
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/node/PrintTestSupport.java9
4 files changed, 54 insertions, 0 deletions
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter10Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter10Test.java
index a96da02c..029e28b8 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter10Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter10Test.java
@@ -6,6 +6,21 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class Chapter10Test {
+ @Test public void testDeadReferenceReturn() {
+ for( String body : new String[] {
+ "return new S; return 0;",
+ "if(1) return new S; else return 0;"
+ } ) {
+ String src = "struct S { int x; }; " + body;
+ var code = new CodeGen(src).parse().opto().typeCheck();
+ // This chapter also has constructor/class-init Returns in the CompUnit.
+ var entry = (com.seaofnodes.simple.node.FunNode)code._start.uctrl();
+ org.junit.Assert.assertTrue(body,
+ entry.ret().expr()._type instanceof com.seaofnodes.simple.type.TypeMemPtr);
+ }
+ }
+
+
private static final String NULLABLE_POINT_SOURCE = """
struct Point { int x; new Point = { int v -> x = v; }; };
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java
index 85317644..4b2d48d8 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java
@@ -5,6 +5,20 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class Chapter12Test {
+ @Test public void testDeadNumericReturns() {
+ for( String[] test : new String[][] {
+ {"if(1) return 7; else return 2.5;", "7"},
+ {"if(0) return 7; else return 2.5;", "2.5"},
+ {"return 7; return 2.5;", "7"},
+ {"return 2.5; return 7;", "2.5"}
+ } ) {
+ String src = test[0];
+ var code = new CodeGen(src).parse().opto().typeCheck();
+ assertEquals(src,test[1],Eval2.eval(code,0));
+ }
+ }
+
+
@Test
public void testJig() {
CodeGen code = new CodeGen(
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter18Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter18Test.java
index d7fd12ff..4cf19746 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter18Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter18Test.java
@@ -11,6 +11,22 @@ import static org.junit.Assert.*;
import static org.junit.Assert.fail;
public class Chapter18Test {
+ @Test public void testReachableMixedReturns() {
+ for( String[] test : new String[][] {
+ {"if(arg) return 7; else return 2.5;", "No common type amongst int and f64"},
+ {"struct S { int x; }; if(arg) return new S; else return 0;",
+ "No common type amongst int and reference"}
+ } ) {
+ try {
+ new CodeGen(test[0]).parse().opto().typeCheck();
+ fail("Expected incompatible return types: " + test[0]);
+ } catch( Parser.ParseException e ) {
+ assertEquals("Cannot return generic scalar",e.getMessage());
+ }
+ }
+ }
+
+
@Test public void testPrintingForwardReferenceScope() throws Exception {
new CodeGen("return 0;").parse();
var declared = TypeMemPtr.make(TypeStruct.make("PrintForward",true,true));
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/node/PrintTestSupport.java b/chapter25/src/test/java/com/seaofnodes/simple/node/PrintTestSupport.java
index 70d9071a..ceea1de5 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/node/PrintTestSupport.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/node/PrintTestSupport.java
@@ -21,15 +21,24 @@ public class PrintTestSupport {
var ins = new IdentityHashMap<Node,Node[]>();
var outs = new IdentityHashMap<Node,Node[]>();
var hashes = new IdentityHashMap<Node,Integer>();
+ var versions = new IdentityHashMap<Node,Integer>();
var depths = new IdentityHashMap<Node,Integer>();
for( Node n : nodes ) {
ins.put(n,n._inputs.toArray(new Node[0]));
outs.put(n,n._outputs.toArray(new Node[0]));
hashes.put(n,hash.getInt(n));
+ if( n instanceof CFGNode cfg ) {
+ depths.put(n,(int)cfg._idepth);
+ versions.put(n,(int)cfg._idepthVersion);
+ }
}
print.run();
for( Node n : nodes ) {
assertEquals("hash of node "+n._nid,(int)hashes.get(n),hash.getInt(n));
+ if( n instanceof CFGNode cfg ) {
+ assertEquals("depth of node "+n._nid,(int)depths.get(n),cfg._idepth);
+ assertEquals("depth version of node "+n._nid,(int)versions.get(n),cfg._idepthVersion);
+ }
assertEquals(ins.get(n).length,n.nIns());
assertEquals(outs.get(n).length,n.nOuts());
for( int i=0; i<n.nIns(); i++ ) assertSame(ins.get(n)[i],n.in(i));