Program: 27144
Project: 27144
Buggy source:
/** 
 * Determine which, if any, of the supported types the call site is. Constant vars are treated differently so that we don't break their const-ness when we decompose the expression. Once the CONSTANT_VAR annotation is used everywhere instead of coding conventions, we should just teach this pass how to remove the annotation.
 */
private CallSiteType classifyCallSite(Reference ref){
  Node callNode=ref.callNode;
  Node parent=callNode.getParent();
  Node grandParent=parent.getParent();
  if (NodeUtil.isExprCall(parent)) {
    return CallSiteType.SIMPLE_CALL;
  }
 else   if (NodeUtil.isExprAssign(grandParent) && !NodeUtil.isNameDeclOrSimpleAssignLhs(callNode,parent) && parent.getFirstChild().isName()&& !NodeUtil.isConstantName(parent.getFirstChild())) {
    return CallSiteType.SIMPLE_ASSIGNMENT;
  }
 else   if (parent.isName() && !NodeUtil.isConstantName(parent) && (grandParent.isVar() || grandParent.isLet())&& grandParent.hasOneChild()) {
    return CallSiteType.VAR_DECL_SIMPLE_ASSIGNMENT;
  }
 else {
    Node expressionRoot=ExpressionDecomposer.findExpressionRoot(callNode);
    if (expressionRoot != null) {
      ExpressionDecomposer decomposer=getDecomposer(ref.scope);
      DecompositionType type=decomposer.canExposeExpression(callNode);
      if (type == DecompositionType.MOVABLE) {
        return CallSiteType.EXPRESSION;
      }
 else       if (type == DecompositionType.DECOMPOSABLE) {
        return CallSiteType.DECOMPOSABLE_EXPRESSION;
      }
 else {
        checkState(type == DecompositionType.UNDECOMPOSABLE);
      }
    }
  }
  return CallSiteType.UNSUPPORTED;
}

Fixed version (ground truth):
/** 
 * Determine which, if any, of the supported types the call site is. Constant vars are treated differently so that we don't break their const-ness when we decompose the expression. Once the CONSTANT_VAR annotation is used everywhere instead of coding conventions, we should just teach this pass how to remove the annotation.
 */
private CallSiteType classifyCallSite(Reference ref){
  Node callNode=ref.callNode;
  Node parent=callNode.getParent();
  Node grandParent=parent.getParent();
  if (NodeUtil.isExprCall(parent)) {
    return CallSiteType.SIMPLE_CALL;
  }
 else   if (NodeUtil.isExprAssign(grandParent) && !NodeUtil.isNameDeclOrSimpleAssignLhs(callNode,parent) && parent.getFirstChild().isName()&& !NodeUtil.isConstantName(parent.getFirstChild())) {
    return CallSiteType.SIMPLE_ASSIGNMENT;
  }
 else   if (parent.isName() && !NodeUtil.isConstantName(parent) && grandParent.isVar()&& grandParent.hasOneChild()) {
    return CallSiteType.VAR_DECL_SIMPLE_ASSIGNMENT;
  }
 else {
    Node expressionRoot=ExpressionDecomposer.findExpressionRoot(callNode);
    if (expressionRoot != null) {
      ExpressionDecomposer decomposer=getDecomposer(ref.scope);
      DecompositionType type=decomposer.canExposeExpression(callNode);
      if (type == DecompositionType.MOVABLE) {
        return CallSiteType.EXPRESSION;
      }
 else       if (type == DecompositionType.DECOMPOSABLE) {
        return CallSiteType.DECOMPOSABLE_EXPRESSION;
      }
 else {
        checkState(type == DecompositionType.UNDECOMPOSABLE);
      }
    }
  }
  return CallSiteType.UNSUPPORTED;
}