Program: 27154
Project: 27154
Buggy source:
private void computeMayUse(Node n,Node cfgNode,ReachingUses output,boolean conditional){
switch (n.getToken()) {
case BLOCK:
case ROOT:
case FUNCTION:
    return;
case NAME:
  addToUseIfLocal(n.getString(),cfgNode,output);
return;
case WHILE:
case DO:
case IF:
computeMayUse(NodeUtil.getConditionExpression(n),cfgNode,output,conditional);
return;
case FOR:
computeMayUse(NodeUtil.getConditionExpression(n),cfgNode,output,conditional);
return;
case FOR_IN:
Node lhs=n.getFirstChild();
Node rhs=lhs.getNext();
if (lhs.isVar()) {
lhs=lhs.getLastChild();
}
if (lhs.isName() && !conditional) {
removeFromUseIfLocal(lhs.getString(),output);
}
computeMayUse(rhs,cfgNode,output,conditional);
return;
case AND:
case OR:
computeMayUse(n.getLastChild(),cfgNode,output,true);
computeMayUse(n.getFirstChild(),cfgNode,output,conditional);
return;
case HOOK:
computeMayUse(n.getLastChild(),cfgNode,output,true);
computeMayUse(n.getSecondChild(),cfgNode,output,true);
computeMayUse(n.getFirstChild(),cfgNode,output,conditional);
return;
case VAR:
Node varName=n.getFirstChild();
Preconditions.checkState(n.hasChildren(),"String_Node_Str",n);
if (varName.hasChildren()) {
computeMayUse(varName.getFirstChild(),cfgNode,output,conditional);
if (!conditional) {
removeFromUseIfLocal(varName.getString(),output);
}
}
return;
default :
if (NodeUtil.isAssignmentOp(n) && n.getFirstChild().isName()) {
Node name=n.getFirstChild();
if (!conditional) {
removeFromUseIfLocal(name.getString(),output);
}
if (!n.isAssign()) {
addToUseIfLocal(name.getString(),cfgNode,output);
}
computeMayUse(name.getNext(),cfgNode,output,conditional);
}
 else {
for (Node c=n.getLastChild(); c != null; c=c.getPrevious()) {
computeMayUse(c,cfgNode,output,conditional);
}
}
}
}

Fixed version (ground truth):
private void computeMayUse(Node n,Node cfgNode,ReachingUses output,boolean conditional){
switch (n.getToken()) {
case BLOCK:
case ROOT:
case FUNCTION:
    return;
case NAME:
  if (NodeUtil.isLhsByDestructuring(n)) {
    if (!conditional) {
      removeFromUseIfLocal(n.getString(),output);
    }
  }
 else {
    addToUseIfLocal(n.getString(),cfgNode,output);
  }
return;
case WHILE:
case DO:
case IF:
computeMayUse(NodeUtil.getConditionExpression(n),cfgNode,output,conditional);
return;
case FOR:
computeMayUse(NodeUtil.getConditionExpression(n),cfgNode,output,conditional);
return;
case FOR_IN:
Node lhs=n.getFirstChild();
Node rhs=lhs.getNext();
if (lhs.isVar()) {
lhs=lhs.getLastChild();
}
if (lhs.isName() && !conditional) {
removeFromUseIfLocal(lhs.getString(),output);
}
computeMayUse(rhs,cfgNode,output,conditional);
return;
case AND:
case OR:
computeMayUse(n.getLastChild(),cfgNode,output,true);
computeMayUse(n.getFirstChild(),cfgNode,output,conditional);
return;
case HOOK:
computeMayUse(n.getLastChild(),cfgNode,output,true);
computeMayUse(n.getSecondChild(),cfgNode,output,true);
computeMayUse(n.getFirstChild(),cfgNode,output,conditional);
return;
case VAR:
Node varName=n.getFirstChild();
checkState(n.hasChildren(),"String_Node_Str",n);
if (varName.isDestructuringLhs()) {
computeMayUse(varName.getFirstChild(),cfgNode,output,conditional);
computeMayUse(varName.getSecondChild(),cfgNode,output,conditional);
}
 else if (varName.hasChildren()) {
computeMayUse(varName.getFirstChild(),cfgNode,output,conditional);
if (!conditional) {
removeFromUseIfLocal(varName.getString(),output);
}
}
return;
default :
if (NodeUtil.isAssignmentOp(n) && n.getFirstChild().isName()) {
Node name=n.getFirstChild();
if (!conditional) {
removeFromUseIfLocal(name.getString(),output);
}
if (!n.isAssign()) {
addToUseIfLocal(name.getString(),cfgNode,output);
}
computeMayUse(name.getNext(),cfgNode,output,conditional);
}
 else {
for (Node c=n.getLastChild(); c != null; c=c.getPrevious()) {
computeMayUse(c,cfgNode,output,conditional);
}
}
}
}