From 6f427f9fa518d4b37d85db349f7ada65b5a64abd Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Sat, 15 Aug 2009 15:58:49 +0000 Subject: [PATCH] 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 --- pmd/etc/changelog.txt | 1 + .../rules/basic/xml/DoubleCheckedLocking.xml | 44 +++++++++++++++++++ .../pmd/rules/DoubleCheckedLocking.java | 35 +++++++++++---- 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/pmd/etc/changelog.txt b/pmd/etc/changelog.txt index d972fecef7..8f21b9705e 100644 --- a/pmd/etc/changelog.txt +++ b/pmd/etc/changelog.txt @@ -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. diff --git a/pmd/regress/test/net/sourceforge/pmd/rules/basic/xml/DoubleCheckedLocking.xml b/pmd/regress/test/net/sourceforge/pmd/rules/basic/xml/DoubleCheckedLocking.xml index 4cee14ef76..38f9ebbeed 100644 --- a/pmd/regress/test/net/sourceforge/pmd/rules/basic/xml/DoubleCheckedLocking.xml +++ b/pmd/regress/test/net/sourceforge/pmd/rules/basic/xml/DoubleCheckedLocking.xml @@ -55,4 +55,48 @@ public class Foo { ]]> java 1.5 + + + 1 + + + + + 1 + + diff --git a/pmd/src/net/sourceforge/pmd/rules/DoubleCheckedLocking.java b/pmd/src/net/sourceforge/pmd/rules/DoubleCheckedLocking.java index ae3ad71f69..747ddb8371 100644 --- a/pmd/src/net/sourceforge/pmd/rules/DoubleCheckedLocking.java +++ b/pmd/src/net/sourceforge/pmd/rules/DoubleCheckedLocking.java @@ -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()) { @@ -119,12 +120,11 @@ public class DoubleCheckedLocking extends net.sourceforge.pmd.AbstractRule { private boolean ifVerify(ASTIfStatement is, String varname) { List finder = new ArrayList(); 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); + if (finder.size() > 1) { + 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,7 +137,26 @@ public class DoubleCheckedLocking extends net.sourceforge.pmd.AbstractRule { return false; } - private boolean matchName(ASTPrimaryExpression ape, String name) { + /** + *

Sort out if apeLeft or apeRight are variable with the provided 'variableName'.

+ * + * @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); String name2 = getNameFromPrimaryPrefix(pp);