diff --git a/sootup.tests/src/test/java/sootup/tests/InsertBeforeAfterTest.java b/sootup.tests/src/test/java/sootup/tests/InsertBeforeAfterTest.java index 82990eda35..b6985abe72 100644 --- a/sootup.tests/src/test/java/sootup/tests/InsertBeforeAfterTest.java +++ b/sootup.tests/src/test/java/sootup/tests/InsertBeforeAfterTest.java @@ -357,4 +357,314 @@ public void testInsertBeforeBlockMiddle2() { + "}\n"; Assertions.assertEquals(exceptedBody, builder.build().toString()); } + + @Test + public void testInsertAfterBlockTail1() { + + MutableBlockStmtGraph graph = new MutableBlockStmtGraph(body.getStmtGraph()); + List stmts = graph.getStmts(); + // head of a block + String s = "l2 = l2 + 1"; + Stmt afterStmt = null; + for (Stmt stmt : stmts) { + if (stmt.toString().equals(s)) { + afterStmt = stmt; + break; + } + } + + Set newLocals = new HashSet<>(locals); + newLocals.add(l5); + newLocals.add(l6); + + BasicBlock newBlock = + graph.insertAfter( + afterStmt, Arrays.asList(assign1tol5, assign2tol6), Collections.emptyMap()); + Body.BodyBuilder builder = Body.builder(graph); + builder.setLocals(newLocals); + builder.setMethodSignature(methodSignature); + + Assertions.assertEquals(8, graph.getBlocks().size()); + Assertions.assertEquals(2, newBlock.getStmtCount()); + Assertions.assertEquals(1, graph.getBlockOf(afterStmt).getStmtCount()); + Assertions.assertTrue(newBlock.getHead() == assign1tol5); + Assertions.assertTrue(newBlock.getTail() == assign2tol6); + Assertions.assertEquals(0, newBlock.getExceptionalSuccessors().size()); + String expectedBody = + "{\n" + + " TrapBlockCheck this;\n" + + " int l5, l6;\n" + + " unknown $stack3, $stack4, l1, l2;\n" + + "\n" + + "\n" + + " this := @this: TrapBlockCheck;\n" + + " l1 = 0;\n" + + "\n" + + " label1:\n" + + " l2 = 0;\n" + + "\n" + + " if l1 != l2 goto label3;\n" + + " l1 = l1 + 1;\n" + + "\n" + + " goto label5;\n" + + "\n" + + " label2:\n" + + " $stack3 := @caughtexception;\n" + + " l2 = $stack3;\n" + + " $stack4 = new java.lang.RuntimeException;\n" + + " specialinvoke $stack4.(java.lang.String)>(\"error rises!\");\n" + + "\n" + + " throw $stack4;\n" + + "\n" + + " label3:\n" + + " l2 = l2 + 1;\n" + + "\n" + + " label4:\n" + + " l5 = 1;\n" + + " l6 = 2;\n" + + "\n" + + " label5:\n" + + " goto label6;\n" + + "\n" + + " label6:\n" + + " return;\n" + + "\n" + + " catch java.lang.Exception from label1 to label2 with label2;\n" + + " catch java.lang.Exception from label3 to label4 with label2;\n" + + "}\n"; + Assertions.assertEquals(expectedBody, builder.build().toString()); + } + + @Test + public void testInsertAfterBlockTail2() { + + MutableBlockStmtGraph graph = new MutableBlockStmtGraph(body.getStmtGraph()); + List stmts = graph.getStmts(); + // head of a block + String s = "l2 = l2 + 1"; + Stmt afterStmt = null; + for (Stmt stmt : stmts) { + if (stmt.toString().equals(s)) { + afterStmt = stmt; + break; + } + } + Trap trap = graph.buildTraps().get(0); + Map trapMap = + Collections.singletonMap(trap.getExceptionType(), trap.getHandlerStmt()); + + Set newLocals = new HashSet<>(locals); + newLocals.add(l5); + newLocals.add(l6); + + BasicBlock newBlock = + graph.insertAfter(afterStmt, Arrays.asList(assign1tol5, assign2tol6), trapMap); + Body.BodyBuilder builder = Body.builder(graph); + builder.setLocals(newLocals); + builder.setMethodSignature(methodSignature); + + Assertions.assertEquals(7, graph.getBlocks().size()); + Assertions.assertEquals(3, newBlock.getStmtCount()); + Assertions.assertEquals(3, graph.getBlockOf(afterStmt).getStmtCount()); + Assertions.assertTrue(newBlock.getHead() == afterStmt); + Assertions.assertTrue(newBlock.getTail() == assign2tol6); + Assertions.assertEquals(1, newBlock.getExceptionalSuccessors().size()); + String expectedBody = + "{\n" + + " TrapBlockCheck this;\n" + + " int l5, l6;\n" + + " unknown $stack3, $stack4, l1, l2;\n" + + "\n" + + "\n" + + " this := @this: TrapBlockCheck;\n" + + " l1 = 0;\n" + + "\n" + + " label1:\n" + + " l2 = 0;\n" + + "\n" + + " if l1 != l2 goto label3;\n" + + " l1 = l1 + 1;\n" + + "\n" + + " goto label4;\n" + + "\n" + + " label2:\n" + + " $stack3 := @caughtexception;\n" + + " l2 = $stack3;\n" + + " $stack4 = new java.lang.RuntimeException;\n" + + " specialinvoke $stack4.(java.lang.String)>(\"error rises!\");\n" + + "\n" + + " throw $stack4;\n" + + "\n" + + " label3:\n" + + " l2 = l2 + 1;\n" + + " l5 = 1;\n" + + " l6 = 2;\n" + + "\n" + + " label4:\n" + + " goto label5;\n" + + "\n" + + " label5:\n" + + " return;\n" + + "\n" + + " catch java.lang.Exception from label1 to label2 with label2;\n" + + " catch java.lang.Exception from label3 to label4 with label2;\n" + + "}\n"; + Assertions.assertEquals(expectedBody, builder.build().toString()); + } + + @Test + public void testInsertAfterBlockMiddle1() { + + MutableBlockStmtGraph graph = new MutableBlockStmtGraph(body.getStmtGraph()); + List stmts = graph.getStmts(); + // middle stmt of a block + String s = "l2 = 0"; + Stmt afterStmt = null; + for (Stmt stmt : stmts) { + if (stmt.toString().equals(s)) { + afterStmt = stmt; + break; + } + } + + Set newLocals = new HashSet<>(locals); + newLocals.add(l5); + newLocals.add(l6); + Trap trap = graph.buildTraps().get(0); + Map trapMap = + Collections.singletonMap(trap.getExceptionType(), trap.getHandlerStmt()); + BasicBlock newBlock = + graph.insertAfter(afterStmt, Arrays.asList(assign1tol5, assign2tol6), trapMap); + Body.BodyBuilder builder = Body.builder(graph); + builder.setLocals(newLocals); + builder.setMethodSignature(methodSignature); + + Assertions.assertEquals(7, graph.getBlocks().size()); + Assertions.assertEquals(4, newBlock.getStmtCount()); + Assertions.assertTrue(graph.getBlockOf(afterStmt) == newBlock); + Assertions.assertTrue(newBlock.getHead().toString().equals("l2 = 0")); + Assertions.assertTrue(newBlock.getTail().toString().equals("if l1 != l2")); + Assertions.assertEquals(1, newBlock.getExceptionalSuccessors().size()); + + String exceptedBody = + "{\n" + + " TrapBlockCheck this;\n" + + " int l5, l6;\n" + + " unknown $stack3, $stack4, l1, l2;\n" + + "\n" + + "\n" + + " this := @this: TrapBlockCheck;\n" + + " l1 = 0;\n" + + "\n" + + " label1:\n" + + " l2 = 0;\n" + + " l5 = 1;\n" + + " l6 = 2;\n" + + "\n" + + " if l1 != l2 goto label3;\n" + + " l1 = l1 + 1;\n" + + "\n" + + " goto label4;\n" + + "\n" + + " label2:\n" + + " $stack3 := @caughtexception;\n" + + " l2 = $stack3;\n" + + " $stack4 = new java.lang.RuntimeException;\n" + + " specialinvoke $stack4.(java.lang.String)>(\"error rises!\");\n" + + "\n" + + " throw $stack4;\n" + + "\n" + + " label3:\n" + + " l2 = l2 + 1;\n" + + "\n" + + " label4:\n" + + " goto label5;\n" + + "\n" + + " label5:\n" + + " return;\n" + + "\n" + + " catch java.lang.Exception from label1 to label2 with label2;\n" + + " catch java.lang.Exception from label3 to label4 with label2;\n" + + "}\n"; + Assertions.assertEquals(exceptedBody, builder.build().toString()); + } + + @Test + public void testInsertAfterBlockMiddle2() { + + MutableBlockStmtGraph graph = new MutableBlockStmtGraph(body.getStmtGraph()); + List stmts = graph.getStmts(); + // middle stmt of a block + String s = "l2 = 0"; + Stmt afterStmt = null; + for (Stmt stmt : stmts) { + if (stmt.toString().equals(s)) { + afterStmt = stmt; + break; + } + } + + Set newLocals = new HashSet<>(locals); + newLocals.add(l5); + newLocals.add(l6); + BasicBlock newBlock = + graph.insertAfter( + afterStmt, Arrays.asList(assign1tol5, assign2tol6), Collections.emptyMap()); + Body.BodyBuilder builder = Body.builder(graph); + builder.setLocals(newLocals); + builder.setMethodSignature(methodSignature); + + Assertions.assertEquals(9, graph.getBlocks().size()); + Assertions.assertEquals(2, newBlock.getStmtCount()); + Assertions.assertTrue(graph.getBlockOf(afterStmt) != graph.getBlockOf(assign1tol5)); + Assertions.assertTrue(newBlock.getHead().toString().equals("l5 = 1")); + Assertions.assertTrue(newBlock.getTail().toString().equals("l6 = 2")); + Assertions.assertEquals(0, newBlock.getExceptionalSuccessors().size()); + + String exceptedBody = + "{\n" + + " TrapBlockCheck this;\n" + + " int l5, l6;\n" + + " unknown $stack3, $stack4, l1, l2;\n" + + "\n" + + "\n" + + " this := @this: TrapBlockCheck;\n" + + " l1 = 0;\n" + + "\n" + + " label1:\n" + + " l2 = 0;\n" + + "\n" + + " label2:\n" + + " l5 = 1;\n" + + " l6 = 2;\n" + + "\n" + + " label3:\n" + + " if l1 != l2 goto label5;\n" + + " l1 = l1 + 1;\n" + + "\n" + + " goto label6;\n" + + "\n" + + " label4:\n" + + " $stack3 := @caughtexception;\n" + + " l2 = $stack3;\n" + + " $stack4 = new java.lang.RuntimeException;\n" + + " specialinvoke $stack4.(java.lang.String)>(\"error rises!\");\n" + + "\n" + + " throw $stack4;\n" + + "\n" + + " label5:\n" + + " l2 = l2 + 1;\n" + + "\n" + + " label6:\n" + + " goto label7;\n" + + "\n" + + " label7:\n" + + " return;\n" + + "\n" + + " catch java.lang.Exception from label1 to label2 with label4;\n" + + " catch java.lang.Exception from label3 to label4 with label4;\n" + + " catch java.lang.Exception from label5 to label6 with label4;\n" + + "}\n"; + Assertions.assertEquals(exceptedBody, builder.build().toString()); + } }