summaryrefslogtreecommitdiff
path: root/chapter24/src
diff options
context:
space:
mode:
Diffstat (limited to 'chapter24/src')
-rw-r--r--chapter24/src/main/java/com/seaofnodes/simple/node/ArithFNode.java2
-rw-r--r--chapter24/src/main/java/com/seaofnodes/simple/node/ArithNode.java4
-rw-r--r--chapter24/src/main/java/com/seaofnodes/simple/node/LoadNode.java1
-rw-r--r--chapter24/src/test/java/com/seaofnodes/simple/Chapter10Test.java6
-rw-r--r--chapter24/src/test/java/com/seaofnodes/simple/Chapter16Test.java13
5 files changed, 14 insertions, 12 deletions
diff --git a/chapter24/src/main/java/com/seaofnodes/simple/node/ArithFNode.java b/chapter24/src/main/java/com/seaofnodes/simple/node/ArithFNode.java
index 7fa428c6..3c20fa6e 100644
--- a/chapter24/src/main/java/com/seaofnodes/simple/node/ArithFNode.java
+++ b/chapter24/src/main/java/com/seaofnodes/simple/node/ArithFNode.java
@@ -20,7 +20,7 @@ public abstract class ArithFNode extends Node {
public Type compute() {
Type t1 = in(1)._type, t2 = in(2)._type;
if( t1.isHigh() || t2.isHigh() )
- return TypeFloat.TOP;
+ return Type.TOP;
if( t1 instanceof TypeFloat f1 &&
t2 instanceof TypeFloat f2 ) {
if( f1.isConstant() && f2.isConstant() )
diff --git a/chapter24/src/main/java/com/seaofnodes/simple/node/ArithNode.java b/chapter24/src/main/java/com/seaofnodes/simple/node/ArithNode.java
index 6c147fe8..e9a60f50 100644
--- a/chapter24/src/main/java/com/seaofnodes/simple/node/ArithNode.java
+++ b/chapter24/src/main/java/com/seaofnodes/simple/node/ArithNode.java
@@ -26,10 +26,10 @@ public abstract class ArithNode extends Node {
// Generic airthmetic op math: high returns high; low returns low; 2
// constants fold; only 2 non-constants call specialized math.
@Override
- public final TypeInteger compute() {
+ public final Type compute() {
Type t1 = in(1)._type, t2 = in(2)._type;
if( t1.isHigh() || t2.isHigh() )
- return TypeInteger.TOP;
+ return Type.TOP;
if( t1 instanceof TypeInteger x &&
t2 instanceof TypeInteger y )
return x.isConstant() && y.isConstant()
diff --git a/chapter24/src/main/java/com/seaofnodes/simple/node/LoadNode.java b/chapter24/src/main/java/com/seaofnodes/simple/node/LoadNode.java
index b32484c2..5f28a39b 100644
--- a/chapter24/src/main/java/com/seaofnodes/simple/node/LoadNode.java
+++ b/chapter24/src/main/java/com/seaofnodes/simple/node/LoadNode.java
@@ -174,6 +174,7 @@ public class LoadNode extends MemOpNode {
private Node zero(NewNode nnn) {
TypeStruct ts = nnn._ptr._obj;
Type zero = ts._fields[ts.findAlias(_alias)]._t.makeZero();
+ assert zero.isa(_type); // Catch an uninitialized non-null field
return castRO(new ConstantNode(zero).peephole());
}
diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Chapter10Test.java b/chapter24/src/test/java/com/seaofnodes/simple/Chapter10Test.java
index d7a74f18..3c5a2913 100644
--- a/chapter24/src/test/java/com/seaofnodes/simple/Chapter10Test.java
+++ b/chapter24/src/test/java/com/seaofnodes/simple/Chapter10Test.java
@@ -63,6 +63,7 @@ public class Chapter10Test {
public void testNullGuardErrors() {
for( String body : new String[] {
"return p.x;",
+ "if (p == null) return p.x; return -1;",
"if (!!points) return p.x; return -1;",
"if (!!p) { int x = p.x; } return p.x;"
} ) {
@@ -70,7 +71,10 @@ public class Chapter10Test {
new CodeGen(NULLABLE_POINT_SOURCE+body).parse().opto().typeCheck();
fail(body);
} catch( RuntimeException e ) {
- assertEquals(body,"Might be null accessing 'x'",e.getMessage());
+ // Known null is rejected during parsing in these chapters.
+ String expected = body.startsWith("if (p == null)")
+ ? "Accessing unknown field 'x' from 'null'" : "Might be null accessing 'x'";
+ assertEquals(body,expected,e.getMessage());
}
}
}
diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Chapter16Test.java b/chapter24/src/test/java/com/seaofnodes/simple/Chapter16Test.java
index 2623fee5..310efc45 100644
--- a/chapter24/src/test/java/com/seaofnodes/simple/Chapter16Test.java
+++ b/chapter24/src/test/java/com/seaofnodes/simple/Chapter16Test.java
@@ -143,14 +143,11 @@ return p;
@Test
public void testStructFinal3() {
- CodeGen code = new CodeGen("""
-struct Point { var x; var y; };
-Point p = new Point;
-p.x++;
-return p;
-""");
- try { code.parse().opto(); fail(); }
- catch( Exception e ) { assertEquals("'Point' is not fully initialized, field 'x' needs to be set in a constructor",e.getMessage()); }
+ for( String fields : new String[] { "var x; var y;", "int[] x;", "int[] !x;" } ) {
+ String src = "struct Point { "+fields+" }; Point p = new Point; p.x++; return p;";
+ try { new CodeGen(src).parse().opto(); fail(fields); }
+ catch( Exception e ) { assertEquals("'Point' is not fully initialized, field 'x' needs to be set in a constructor",e.getMessage()); }
+ }
}
@Test