From c7a3752481c3c33cc7e460a75daf2a07d2c15c25 Mon Sep 17 00:00:00 2001 From: XmiliaH <45106915+XmiliaH@users.noreply.github.com> Date: Sat, 28 Oct 2023 23:37:22 +0200 Subject: set_def might kill new_def in kill recursion caused by old_def being killed (#18) --- chapter04/src/main/java/com/seaofnodes/simple/node/Node.java | 8 +++++--- chapter04/src/test/java/com/seaofnodes/simple/Chapter04Test.java | 7 +++++++ 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'chapter04') diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter04/src/main/java/com/seaofnodes/simple/node/Node.java index 8d698d1b..7cc9291c 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/Node.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/Node.java @@ -193,14 +193,16 @@ public abstract class Node { Node set_def(int idx, Node new_def ) { Node old_def = in(idx); if( old_def == new_def ) return this; // No change + // If new def is not null, add the corresponding def->use edge + // This needs to happen before removing the old node's def->use edge as + // the new_def might get killed if the old node kills it recursively. + if( new_def != null ) + new_def._outputs.add(this); if( old_def != null && // If the old def exists, remove a def->use edge old_def.delUse(this) ) // If we removed the last use, the old def is now dead old_def.kill(); // Kill old def // Set the new_def over the old (killed) edge _inputs.set(idx,new_def); - // If new def is not null, add the corresponding def->use edge - if( new_def != null ) - new_def._outputs.add(this); // Return self for easy flow-coding return this; } diff --git a/chapter04/src/test/java/com/seaofnodes/simple/Chapter04Test.java b/chapter04/src/test/java/com/seaofnodes/simple/Chapter04Test.java index 8cc78af0..4782e568 100644 --- a/chapter04/src/test/java/com/seaofnodes/simple/Chapter04Test.java +++ b/chapter04/src/test/java/com/seaofnodes/simple/Chapter04Test.java @@ -112,6 +112,13 @@ public class Chapter04Test { assertEquals("return (Proj_3+1);", ret.print()); } + @Test + public void testChapter4Bug3() { + Parser parser = new Parser("int a=arg*2+1; a=a+-1; return a; #showGraph;", TypeInteger.BOT); + ReturnNode ret = parser.parse(); + assertEquals("return (Proj_3*2);", ret.print()); + } + @Test public void testVarDecl() { Parser parser = new Parser("int a=1; return a;"); -- cgit v1.2.3