Currently, the False Positive of java -try-catch is a common issue. Like this:
InputStream is = null;
try {
is = new InputStream("no_such_file");
} catch (Exception e) {
}
try {
if (is != null) {
is.close();
}
} catch (Exception e) {
}
The above code snippet will be report as "InputStream" should be close.
The root cause is in "org/sonar/java/cfg/CFG.java" line 790 in function buildTryStatement().
for (Block catchBlock : catches) {
currentBlock.addSuccessor(catchBlock);
}
Here, the catch block was being added as a branch of try block. So, in CFG, the above code snippet is:
InputStream is = null;
/ \
/ \
is=new ... // Empty catch block
\ /
\ /
// Empty block
/ \
/ \
if (is != null) ... // Empty catch block
\ /
\ /
function exit...
So, it is not so hard to understand the False Positive now.
How to resolve this False Positive? It is quite hard because CFG want to simulate try-catch via branch mechanism. However, we can use a some simple, tricky solution to decrease those kind of False Positive.
1. go through the all blocks inside try-block, and found out the first possible exception occupation point.
2. break this block before(or after) the exception occupation point according to the expression type. (normal expression - after, new-object expression - before)
3. add the catch-block as a branch of the remains of this block.
So, the CFG of the above code snippet will be:
InputStream is = null;
/ \
/ \
is=new ... // Empty catch block
\ /
\ /
// Empty block
|
|
if (is != null) ...
/ \
/ \
\ // Empty catch block
\ /
\ /
function exit ...
So, the False Positive is GONE!!!
The attachment is my patch. And, I think if we find out all the possible exception occupation point, the result should be more accurate. But the number of branches may be too many.