Skip to content

filtering JAVAC.FINALLY

Evgeny Mandrikov edited this page Oct 2, 2017 · 13 revisions

This page discusses a not yet available feature!

Related discussions

Description

A finally block is executed in the following situations:

  1. The associated code block executes without exception
  2. An exception occurs which has a catch block declared
  3. An exceptions occurs in the associated code block which has no catch block declared

For this the Java compiler emits the code for the finally block multiple times:

2 + (number of catch blocks)

This results in unexpected coverage results. E.g. a simple if statement within a finally block is reported as 4 branches.

Filtering

The identical blocks in exception handles should be merged blocks into a single one. Also probe information should be merged. For example if there are two branches A and B where A is covered in the normal case and B is covered in an exceptional case this should be reported as full branch coverage.

Source Example

void open() throws IOException;

void example() throws IOException {
  Closeable resource = null;
  try {
      resource = open();
      // do something with resource
  } finally { // this block is emitted twice:
    if (resource != null) {
      resource.close(); // not executed on exception path from method `open`
    }
  }
}

Bytecode Pattern

ECJ

label_1:
  <associated code block>
  GOTO label_4
label_2:
  ...
label_3:
  ASTORE n
  <finally code>
  ALOAD n
  ATHROW
label_4:
  <finally code>

Exception Table:
  [pc: label_1, label_2] -> label_3 when : any

javac

label_1:
  <associated code block>
label_2:
  <finally code>
  GOTO label_4
  ...
label_3:
  ASTORE n
  <finally code>
  ALOAD n
  ATHROW
label_4:
  ...

Exception Table:
  [pc: label_1, label_2] -> label_3 when : any