forked from phoedos/pmd
Fixing bug : False -: DoubleCheckedLocking with reversed null check - ID: 2835074
git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/branches/pmd/4.2.x@6976 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
@ -5,6 +5,7 @@ Fixed bug 2317099 - False + in SimplifyCondition
|
||||
Fixed bug 2606609 - False "UnusedImports" positive in package-info.java
|
||||
Fixed bug 2645268 - ClassCastException in UselessOperationOnImmutable.getDeclaration
|
||||
Fixed bug 2724653 - AvoidThreadGroup reports false positives
|
||||
Fixed bug 2835074 - False -: DoubleCheckedLocking with reversed null check
|
||||
Correct -benchmark reporting of Rule visits via the RuleChain
|
||||
Fix issue with Type Resolution incorrectly handling of Classes with same name as a java.lang Class.
|
||||
|
||||
|
@ -55,4 +55,48 @@ public class Foo {
|
||||
]]></code>
|
||||
<source-type>java 1.5</source-type>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
inversed null check -see bug 2835074 False -: DoubleCheckedLocking with reversed null check
|
||||
2835074 False -: DoubleCheckedLocking with reversed null check
|
||||
]]></description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
Object baz;
|
||||
Object bar() {
|
||||
if(null == baz) { //baz may be non-null yet not fully created
|
||||
synchronized(this){
|
||||
if(baz == null){
|
||||
baz = new Object();
|
||||
}
|
||||
}
|
||||
}
|
||||
return baz;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
inversed null check -see bug 2835074 False -: DoubleCheckedLocking with reversed null check
|
||||
2835074 False -: DoubleCheckedLocking with reversed null check
|
||||
]]></description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
Object baz;
|
||||
Object bar() {
|
||||
if(baz == null) { //baz may be non-null yet not fully created
|
||||
synchronized(this){
|
||||
if(null == baz){
|
||||
baz = new Object();
|
||||
}
|
||||
}
|
||||
}
|
||||
return baz;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
</test-data>
|
||||
|
@ -3,6 +3,7 @@
|
||||
*/
|
||||
package net.sourceforge.pmd.rules;
|
||||
|
||||
import net.sourceforge.pmd.AbstractJavaRule;
|
||||
import net.sourceforge.pmd.ast.ASTAssignmentOperator;
|
||||
import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.ast.ASTIfStatement;
|
||||
@ -41,7 +42,7 @@ import java.util.List;
|
||||
*
|
||||
* @author CL Gilbert (dnoyeb@users.sourceforge.net)
|
||||
*/
|
||||
public class DoubleCheckedLocking extends net.sourceforge.pmd.AbstractRule {
|
||||
public class DoubleCheckedLocking extends AbstractJavaRule {
|
||||
|
||||
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
|
||||
if (node.isInterface()) {
|
||||
@ -120,11 +121,10 @@ public class DoubleCheckedLocking extends net.sourceforge.pmd.AbstractRule {
|
||||
List<ASTPrimaryExpression> finder = new ArrayList<ASTPrimaryExpression>();
|
||||
is.findChildrenOfType(ASTPrimaryExpression.class, finder, true);
|
||||
if (finder.size() > 1) {
|
||||
ASTPrimaryExpression apeLeft = finder.get(0);
|
||||
if (matchName(apeLeft, varname)) {
|
||||
ASTPrimaryExpression apeRight = finder.get(1);
|
||||
if ((apeRight.jjtGetNumChildren() == 1) && (apeRight.jjtGetChild(0) instanceof ASTPrimaryPrefix)) {
|
||||
ASTPrimaryPrefix pp2 = (ASTPrimaryPrefix) apeRight.jjtGetChild(0);
|
||||
ASTPrimaryExpression nullStmt = findNonVariableStmt(varname,finder.get(0),finder.get(1));
|
||||
if ( nullStmt != null ) {
|
||||
if ((nullStmt.jjtGetNumChildren() == 1) && (nullStmt.jjtGetChild(0) instanceof ASTPrimaryPrefix)) {
|
||||
ASTPrimaryPrefix pp2 = (ASTPrimaryPrefix) nullStmt.jjtGetChild(0);
|
||||
if ((pp2.jjtGetNumChildren() == 1) && (pp2.jjtGetChild(0) instanceof ASTLiteral)) {
|
||||
ASTLiteral lit = (ASTLiteral) pp2.jjtGetChild(0);
|
||||
if ((lit.jjtGetNumChildren() == 1) && (lit.jjtGetChild(0) instanceof ASTNullLiteral)) {
|
||||
@ -137,6 +137,25 @@ public class DoubleCheckedLocking extends net.sourceforge.pmd.AbstractRule {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sort out if apeLeft or apeRight are variable with the provided 'variableName'.</p>
|
||||
*
|
||||
* @param variableName
|
||||
* @param apeLeft
|
||||
* @param apeRight
|
||||
* @return reference from either apeLeft or apeRight, if one of them match, or 'null', if none match.
|
||||
*/
|
||||
private ASTPrimaryExpression findNonVariableStmt(String variableName,
|
||||
ASTPrimaryExpression apeLeft, ASTPrimaryExpression apeRight) {
|
||||
if (matchName(apeLeft, variableName) ) {
|
||||
return apeRight;
|
||||
}
|
||||
else if (matchName(apeRight, variableName) ) {
|
||||
return apeLeft;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean matchName(ASTPrimaryExpression ape, String name) {
|
||||
if ((ape.jjtGetNumChildren() == 1) && (ape.jjtGetChild(0) instanceof ASTPrimaryPrefix)) {
|
||||
ASTPrimaryPrefix pp = (ASTPrimaryPrefix) ape.jjtGetChild(0);
|
||||
|
Reference in New Issue
Block a user