Program: 27148
Project: 27148
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:
  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:
case FOR_OF:
Node lhs=n.getFirstChild();
Node rhs=lhs.getNext();
if (NodeUtil.isNameDeclaration(lhs)) {
lhs=lhs.getLastChild();
if (lhs.isDestructuringLhs()) {
lhs=lhs.getFirstChild();
}
}
if (lhs.isName() && !conditional) {
removeFromUseIfLocal(lhs.getString(),output);
}
 else if (lhs.isDestructuringPattern()) {
computeMayUse(lhs,cfgNode,output,true);
}
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:
case LET:
case CONST:
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);
}
}
}
}

Fixed version (ground truth):
/** 
 * @param conditional Whether {@code n} is only conditionally evaluated given that {@code cfgNode}is evaluated. Do not remove conditionally redefined variables from the reaching uses set.
 */
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:
case FOR_OF:
Node lhs=n.getFirstChild();
Node rhs=lhs.getNext();
if (NodeUtil.isNameDeclaration(lhs)) {
lhs=lhs.getLastChild();
if (lhs.isDestructuringLhs()) {
lhs=lhs.getFirstChild();
}
}
if (lhs.isName() && !conditional) {
removeFromUseIfLocal(lhs.getString(),output);
}
 else if (lhs.isDestructuringPattern()) {
computeMayUse(lhs,cfgNode,output,true);
}
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:
case LET:
case CONST:
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;
case DEFAULT_VALUE:
if (n.getFirstChild().isDestructuringPattern()) {
computeMayUse(n.getFirstChild(),cfgNode,output,conditional);
computeMayUse(n.getSecondChild(),cfgNode,output,true);
}
 else if (n.getFirstChild().isName()) {
if (!conditional) {
removeFromUseIfLocal(n.getFirstChild().getString(),output);
}
computeMayUse(n.getSecondChild(),cfgNode,output,true);
}
 else {
computeMayUse(n.getSecondChild(),cfgNode,output,true);
computeMayUse(n.getFirstChild(),cfgNode,output,conditional);
}
break;
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 if (n.isAssign() && n.getFirstChild().isDestructuringPattern()) {
computeMayUse(n.getFirstChild(),cfgNode,output,conditional);
computeMayUse(n.getSecondChild(),cfgNode,output,conditional);
}
 else {
for (Node c=n.getLastChild(); c != null; c=c.getPrevious()) {
computeMayUse(c,cfgNode,output,conditional);
}
}
}
}