summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chapter13/src/main/java/com/seaofnodes/simple/Parser.java2
-rw-r--r--chapter13/src/test/java/com/seaofnodes/simple/Chapter13Test.java18
-rw-r--r--chapter14/src/main/java/com/seaofnodes/simple/Parser.java2
-rw-r--r--chapter14/src/test/java/com/seaofnodes/simple/Chapter13Test.java18
-rw-r--r--chapter15/src/main/java/com/seaofnodes/simple/Parser.java6
-rw-r--r--chapter15/src/test/java/com/seaofnodes/simple/Chapter13Test.java18
6 files changed, 59 insertions, 5 deletions
diff --git a/chapter13/src/main/java/com/seaofnodes/simple/Parser.java b/chapter13/src/main/java/com/seaofnodes/simple/Parser.java
index 53448e4d..71bd6d02 100644
--- a/chapter13/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter13/src/main/java/com/seaofnodes/simple/Parser.java
@@ -646,7 +646,7 @@ public class Parser {
}
Type declaredType = base._fields[idx]._type;
- return parsePostfix(new LoadNode(name, alias, declaredType, memAlias(alias), expr).peephole());
+ return parsePostfix(new LoadNode(name, alias, declaredType.glb(), memAlias(alias), expr).peephole());
}
/**
diff --git a/chapter13/src/test/java/com/seaofnodes/simple/Chapter13Test.java b/chapter13/src/test/java/com/seaofnodes/simple/Chapter13Test.java
index 3fc5502e..b425fd85 100644
--- a/chapter13/src/test/java/com/seaofnodes/simple/Chapter13Test.java
+++ b/chapter13/src/test/java/com/seaofnodes/simple/Chapter13Test.java
@@ -163,4 +163,22 @@ return new S1.s=new S2;
StopNode stop = parser.parse().iterate(false);
assertEquals("return new S1;", stop.toString());
}
+
+ @Test
+ public void testcheckNull() {
+ Parser parser = new Parser(
+"""
+struct I {int i;}
+struct P {I pi;}
+P p1 = new P;
+P p2 = new P;
+p2.pi = new I;
+p2.pi.i = 2;
+if (arg) p1 = new P;
+return p1.pi.i + 1;
+""");
+ try { parser.parse(false).iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Might be null accessing 'i'",e.getMessage()); }
+ }
+
}
diff --git a/chapter14/src/main/java/com/seaofnodes/simple/Parser.java b/chapter14/src/main/java/com/seaofnodes/simple/Parser.java
index 417f4295..9e4b9eb6 100644
--- a/chapter14/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter14/src/main/java/com/seaofnodes/simple/Parser.java
@@ -718,7 +718,7 @@ public class Parser {
}
Type declaredType = base._fields[idx]._type;
- return parsePostfix(new LoadNode(name, alias, declaredType, memAlias(alias), expr).peephole());
+ return parsePostfix(new LoadNode(name, alias, declaredType.glb(), memAlias(alias), expr).peephole());
}
// zero/sign extend. "i" is limited to either classic unsigned (min==0) or
diff --git a/chapter14/src/test/java/com/seaofnodes/simple/Chapter13Test.java b/chapter14/src/test/java/com/seaofnodes/simple/Chapter13Test.java
index 62191459..0edb2d51 100644
--- a/chapter14/src/test/java/com/seaofnodes/simple/Chapter13Test.java
+++ b/chapter14/src/test/java/com/seaofnodes/simple/Chapter13Test.java
@@ -163,4 +163,22 @@ return new S1.s=new S2;
StopNode stop = parser.parse().iterate(false);
assertEquals("return new S1;", stop.toString());
}
+
+ @Test
+ public void testcheckNull() {
+ Parser parser = new Parser(
+"""
+struct I {int i;}
+struct P {I pi;}
+P p1 = new P;
+P p2 = new P;
+p2.pi = new I;
+p2.pi.i = 2;
+if (arg) p1 = new P;
+return p1.pi.i + 1;
+""");
+ try { parser.parse(false).iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Might be null accessing 'i'",e.getMessage()); }
+ }
+
}
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
index 012a010e..728aaca7 100644
--- a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
@@ -807,7 +807,7 @@ public class Parser {
val = zsMask(val,f._type);
Node st = new StoreNode(name, f._alias, f._type, memAlias(f._alias), expr, off, val, false);
// Arrays include control, as a proxy for a safety range check.
- // Structs dont need this; they only need a NPE check which is
+ // Structs don't need this; they only need a NPE check which is
// done via the type system.
if( base.isAry() ) st.setDef(0,ctrl());
memAlias(f._alias, st.peephole());
@@ -815,9 +815,9 @@ public class Parser {
}
}
- Node load = new LoadNode(name, f._alias, f._type, memAlias(f._alias), expr, off);
+ Node load = new LoadNode(name, f._alias, f._type.glb(), memAlias(f._alias), expr, off);
// Arrays include control, as a proxy for a safety range check
- // Structs dont need this; they only need a NPE check which is
+ // Structs don't need this; they only need a NPE check which is
// done via the type system.
if( base.isAry() ) load.setDef(0,ctrl());
return parsePostfix(load.peephole());
diff --git a/chapter15/src/test/java/com/seaofnodes/simple/Chapter13Test.java b/chapter15/src/test/java/com/seaofnodes/simple/Chapter13Test.java
index e8b71820..416aba31 100644
--- a/chapter15/src/test/java/com/seaofnodes/simple/Chapter13Test.java
+++ b/chapter15/src/test/java/com/seaofnodes/simple/Chapter13Test.java
@@ -163,4 +163,22 @@ return new S1.s=new S2;
StopNode stop = parser.parse().iterate();
assertEquals("return S2;", stop.toString());
}
+
+ @Test
+ public void testcheckNull() {
+ Parser parser = new Parser(
+"""
+struct I {int i;}
+struct P {I pi;}
+P p1 = new P;
+P p2 = new P;
+p2.pi = new I;
+p2.pi.i = 2;
+if (arg) p1 = new P;
+return p1.pi.i + 1;
+""");
+ try { parser.parse(false).iterate(); fail(); }
+ catch( Exception e ) { assertEquals("Might be null accessing 'i'",e.getMessage()); }
+ }
+
}