Program: 27513
Project: 27513
Buggy source:
/** 
 * If the variable is declared more than once in a basic block, generate a warning. Also check if a variable is used in a given scope before it is declared, which suggest a likely error. Relies on the fact that references is in parse-tree order.
 */
private void checkVar(Var v,List<Reference> references){
  blocksWithDeclarations.clear();
  boolean isDeclaredInScope=false;
  boolean isUnhoistedNamedFunction=false;
  Reference hoistedFn=null;
  for (  Reference reference : references) {
    if (reference.isHoistedFunction()) {
      blocksWithDeclarations.add(reference.getBasicBlock());
      isDeclaredInScope=true;
      hoistedFn=reference;
      break;
    }
 else     if (NodeUtil.isFunctionDeclaration(reference.getNode().getParent())) {
      isUnhoistedNamedFunction=true;
    }
  }
  for (  Reference reference : references) {
    if (reference == hoistedFn) {
      continue;
    }
    BasicBlock basicBlock=reference.getBasicBlock();
    boolean isDeclaration=reference.isDeclaration();
    Node referenceNode=reference.getNode();
    boolean allowDupe=VarCheck.hasDuplicateDeclarationSuppression(referenceNode,v);
    boolean letConstShadowsVar=v.getParentNode().isVar() && (reference.isLetDeclaration() || reference.isConstDeclaration());
    boolean shadowCatchVar=compiler.getLanguageMode().isEs6OrHigher() && v.getParentNode().isCatch() && reference.isDeclaration()&& reference.getNode() != v.getNode();
    boolean shadowDetected=false;
    if (isDeclaration && !allowDupe) {
      for (      BasicBlock declaredBlock : blocksWithDeclarations) {
        if (declaredBlock.provablyExecutesBefore(basicBlock)) {
          shadowDetected=true;
          DiagnosticType diagnosticType;
          if (v.isLet() || v.isConst() || letConstShadowsVar|| shadowCatchVar) {
            diagnosticType=REDECLARED_VARIABLE_ERROR;
          }
 else {
            diagnosticType=REDECLARED_VARIABLE;
          }
          compiler.report(JSError.make(referenceNode,diagnosticType,v.name));
          break;
        }
      }
    }
    if (!shadowDetected && isDeclaration && (letConstShadowsVar || shadowCatchVar)&& v.getScope() == reference.getScope()) {
      compiler.report(JSError.make(referenceNode,REDECLARED_VARIABLE_ERROR,v.name));
    }
    if (isUnhoistedNamedFunction && !isDeclaration && isDeclaredInScope) {
      for (      BasicBlock declaredBlock : blocksWithDeclarations) {
        if (!declaredBlock.provablyExecutesBefore(basicBlock)) {
          compiler.report(JSError.make(referenceNode,AMBIGUOUS_FUNCTION_DECL,v.name));
          break;
        }
      }
    }
    boolean isUndeclaredReference=false;
    if (!isDeclaration && !isDeclaredInScope) {
      if (!referenceNode.isFromExterns()) {
        Node grandparent=reference.getGrandparent();
        if ((v.isVar() && grandparent.isName() && grandparent.getString().equals(v.name))) {
          continue;
        }
        if (reference.getScope() == v.scope && !v.getName().equals("String_Node_Str")) {
          isUndeclaredReference=true;
          compiler.report(JSError.make(reference.getNode(),(v.isLet() || v.isConst() || v.isParam()) ? EARLY_REFERENCE_ERROR : EARLY_REFERENCE,v.name));
        }
      }
    }
    if (!isDeclaration && !isUndeclaredReference && v.isConst()&& reference.isLvalue()) {
      compiler.report(JSError.make(referenceNode,REASSIGNED_CONSTANT,v.name));
    }
    if (isDeclaration && !v.isVar() && reference.getGrandparent().isAddedBlock()) {
      compiler.report(JSError.make(referenceNode,DECLARATION_NOT_DIRECTLY_IN_BLOCK,v.name));
    }
    if (isDeclaration) {
      blocksWithDeclarations.add(basicBlock);
      isDeclaredInScope=true;
    }
  }
}

Fixed version (ground truth):
/** 
 * If the variable is declared more than once in a basic block, generate a warning. Also check if a variable is used in a given scope before it is declared, which suggest a likely error. Relies on the fact that references is in parse-tree order.
 */
private void checkVar(Var v,List<Reference> references){
  blocksWithDeclarations.clear();
  boolean isDeclaredInScope=false;
  boolean isUnhoistedNamedFunction=false;
  Reference hoistedFn=null;
  for (  Reference reference : references) {
    if (reference.isHoistedFunction()) {
      blocksWithDeclarations.add(reference.getBasicBlock());
      isDeclaredInScope=true;
      hoistedFn=reference;
      break;
    }
 else     if (NodeUtil.isFunctionDeclaration(reference.getNode().getParent())) {
      isUnhoistedNamedFunction=true;
    }
  }
  for (  Reference reference : references) {
    if (reference == hoistedFn) {
      continue;
    }
    BasicBlock basicBlock=reference.getBasicBlock();
    boolean isDeclaration=reference.isDeclaration();
    Node referenceNode=reference.getNode();
    boolean allowDupe=VarCheck.hasDuplicateDeclarationSuppression(referenceNode,v);
    boolean letConstShadowsVar=v.getParentNode().isVar() && (reference.isLetDeclaration() || reference.isConstDeclaration());
    boolean shadowCatchVar=compiler.getLanguageMode().isEs6OrHigher() && v.getParentNode().isCatch() && reference.isDeclaration()&& reference.getNode() != v.getNode();
    boolean shadowDetected=false;
    if (isDeclaration && !allowDupe) {
      for (      BasicBlock declaredBlock : blocksWithDeclarations) {
        if (declaredBlock.provablyExecutesBefore(basicBlock)) {
          shadowDetected=true;
          DiagnosticType diagnosticType;
          if (v.isLet() || v.isConst() || letConstShadowsVar|| shadowCatchVar) {
            diagnosticType=REDECLARED_VARIABLE_ERROR;
          }
 else {
            diagnosticType=REDECLARED_VARIABLE;
          }
          compiler.report(JSError.make(referenceNode,diagnosticType,v.name));
          break;
        }
      }
    }
    if (!shadowDetected && isDeclaration && (letConstShadowsVar || shadowCatchVar)&& v.getScope() == reference.getScope()) {
      compiler.report(JSError.make(referenceNode,REDECLARED_VARIABLE_ERROR,v.name));
    }
    if (isUnhoistedNamedFunction && !isDeclaration && isDeclaredInScope) {
      for (      BasicBlock declaredBlock : blocksWithDeclarations) {
        if (!declaredBlock.provablyExecutesBefore(basicBlock)) {
          compiler.report(JSError.make(referenceNode,AMBIGUOUS_FUNCTION_DECL,v.name));
          break;
        }
      }
    }
    boolean isUndeclaredReference=false;
    if (!isDeclaration && !isDeclaredInScope) {
      if (!referenceNode.isFromExterns()) {
        Node grandparent=reference.getGrandparent();
        if ((v.isVar() && grandparent.isName() && grandparent.getString().equals(v.name))) {
          continue;
        }
        if (reference.getScope() == v.scope && !v.getName().equals("String_Node_Str")) {
          isUndeclaredReference=true;
          compiler.report(JSError.make(reference.getNode(),(v.isLet() || v.isConst() || v.isParam()) ? EARLY_REFERENCE_ERROR : EARLY_REFERENCE,v.name));
        }
      }
    }
    if (!isDeclaration && !isUndeclaredReference && v.isConst()&& reference.isLvalue()) {
      compiler.report(JSError.make(referenceNode,REASSIGNED_CONSTANT,v.name));
    }
    if (isDeclaration && !reference.isVarDeclaration() && reference.getGrandparent().isAddedBlock()) {
      compiler.report(JSError.make(referenceNode,DECLARATION_NOT_DIRECTLY_IN_BLOCK,v.name));
    }
    if (isDeclaration) {
      blocksWithDeclarations.add(basicBlock);
      isDeclaredInScope=true;
    }
  }
}