Program: 132541
Project: 132541
Buggy source:
/** 
 * Match abstract argument types to provided argument expressions, Expand variable-length arguments if needed.  Leaves nulls if optional argument was omitted.
 * @param context
 * @param overload
 * @param argTypes
 * @param kwArgTypes
 * @param throwOnFail on failure, return null if falseor throw exception if true
 * @return
 * @throws TypeMismatchException
 * @throws InvalidConstructException
 */
private static List<MatchedArg> matchArgs(Context context,FnOverload overload,List<Type> argTypes,Map<String,Type> kwArgTypes,boolean throwOnFail) throws TypeMismatchException {
  FunctionType fnType=overload.type;
  DefaultVals<Var> defaultVals=overload.defaultVals;
  assert(!fnType.hasVarargs() || !defaultVals.hasAnyDefaults());
  List<Type> abstractInputs=fnType.getInputs();
  int numPosArgs=argTypes.size();
  int numKwArgs=kwArgTypes.size();
  int numTotalArgs=numPosArgs + numKwArgs;
  boolean fixedLength=!defaultVals.hasAnyDefaults() && !fnType.hasVarargs();
  int minNumArgs;
  if (defaultVals.hasAnyDefaults()) {
    minNumArgs=defaultVals.firstDefault();
  }
 else   if (fnType.hasVarargs()) {
    minNumArgs=fnType.getInputs().size() - 1;
  }
 else {
    minNumArgs=fnType.getInputs().size();
  }
  if (numTotalArgs < minNumArgs) {
    if (throwOnFail) {
      throw new TypeMismatchException(context,"String_Node_Str" + "String_Node_Str" + overload.id.originalName() + "String_Node_Str"+ (fixedLength ? "String_Node_Str" : "String_Node_Str")+ "String_Node_Str"+ minNumArgs+ "String_Node_Str"+ numTotalArgs);
    }
    return null;
  }
  if (!fnType.hasVarargs() && numPosArgs > abstractInputs.size()) {
    if (throwOnFail) {
      throw new TypeMismatchException(context,"String_Node_Str" + "String_Node_Str" + overload.id.originalName() + "String_Node_Str"+ abstractInputs.size()+ "String_Node_Str"+ numPosArgs+ "String_Node_Str");
    }
    return null;
  }
  int numMatchedArgs=Math.max(numTotalArgs,fnType.getInputs().size());
  Set<String> unmatchedKwArgs=new HashSet<String>(kwArgTypes.keySet());
  MatchedArg matched[]=new MatchedArg[numMatchedArgs];
  for (int i=0; i < numMatchedArgs; i++) {
    String name;
    Type formalArgType;
    Type argExprType;
    if (i < numPosArgs) {
      argExprType=argTypes.get(i);
      int formalArgIx;
      if (i < abstractInputs.size()) {
        formalArgIx=i;
      }
 else {
        assert(fnType.hasVarargs());
        formalArgIx=abstractInputs.size() - 1;
      }
      name=overload.inArgNames.get(formalArgIx);
      formalArgType=abstractInputs.get(formalArgIx);
    }
 else {
      assert(!fnType.hasVarargs());
      name=overload.inArgNames.get(i);
      boolean hasDefault=overload.defaultVals.defaultVals().get(i) != null;
      if (!hasDefault) {
        throw new TypeMismatchException(context,"String_Node_Str" + name + "String_Node_Str"+ overload.id.originalName());
      }
      formalArgType=abstractInputs.get(i);
      argExprType=kwArgTypes.get(name);
      if (argExprType != null) {
        unmatchedKwArgs.remove(name);
      }
    }
    matched[i]=new MatchedArg(name,formalArgType,argExprType);
  }
  if (unmatchedKwArgs.size() > 0) {
    throw new TypeMismatchException(context,"String_Node_Str" + "String_Node_Str" + overload.id.originalName() + "String_Node_Str"+ unmatchedKwArgs);
  }
  return Arrays.asList(matched);
}

Fixed version (ground truth):
/** 
 * Match abstract argument types to provided argument expressions, Expand variable-length arguments if needed.  Leaves nulls if optional argument was omitted.
 * @param context
 * @param overload
 * @param argTypes
 * @param kwArgTypes
 * @param throwOnFail on failure, return null if falseor throw exception if true
 * @return
 * @throws TypeMismatchException
 * @throws InvalidConstructException
 */
private static List<MatchedArg> matchArgs(Context context,FnOverload overload,List<Type> argTypes,Map<String,Type> kwArgTypes,boolean throwOnFail) throws TypeMismatchException {
  FunctionType fnType=overload.type;
  DefaultVals<Var> defaultVals=overload.defaultVals;
  assert(!fnType.hasVarargs() || !defaultVals.hasAnyDefaults());
  List<Type> abstractInputs=fnType.getInputs();
  int numPosArgs=argTypes.size();
  int numKwArgs=kwArgTypes.size();
  int numTotalArgs=numPosArgs + numKwArgs;
  boolean fixedLength=!defaultVals.hasAnyDefaults() && !fnType.hasVarargs();
  int minNumArgs;
  if (defaultVals.hasAnyDefaults()) {
    minNumArgs=defaultVals.firstDefault();
  }
 else   if (fnType.hasVarargs()) {
    minNumArgs=fnType.getInputs().size() - 1;
  }
 else {
    minNumArgs=fnType.getInputs().size();
  }
  if (numTotalArgs < minNumArgs) {
    if (throwOnFail) {
      throw new TypeMismatchException(context,"String_Node_Str" + "String_Node_Str" + overload.id.originalName() + "String_Node_Str"+ (fixedLength ? "String_Node_Str" : "String_Node_Str")+ "String_Node_Str"+ minNumArgs+ "String_Node_Str"+ numTotalArgs);
    }
    return null;
  }
  if (!fnType.hasVarargs() && numPosArgs > abstractInputs.size()) {
    if (throwOnFail) {
      throw new TypeMismatchException(context,"String_Node_Str" + "String_Node_Str" + overload.id.originalName() + "String_Node_Str"+ abstractInputs.size()+ "String_Node_Str"+ numPosArgs+ "String_Node_Str");
    }
    return null;
  }
  int numMatchedArgs=fnType.hasVarargs() ? numTotalArgs : fnType.getInputs().size();
  Set<String> unmatchedKwArgs=new HashSet<String>(kwArgTypes.keySet());
  MatchedArg matched[]=new MatchedArg[numMatchedArgs];
  for (int i=0; i < numMatchedArgs; i++) {
    String name;
    Type formalArgType;
    Type argExprType;
    if (i < numPosArgs) {
      argExprType=argTypes.get(i);
      int formalArgIx;
      if (i < abstractInputs.size()) {
        formalArgIx=i;
      }
 else {
        assert(fnType.hasVarargs());
        formalArgIx=abstractInputs.size() - 1;
      }
      name=overload.inArgNames.get(formalArgIx);
      formalArgType=abstractInputs.get(formalArgIx);
    }
 else {
      assert(!fnType.hasVarargs());
      name=overload.inArgNames.get(i);
      boolean hasDefault=overload.defaultVals.defaultVals().get(i) != null;
      if (!hasDefault) {
        throw new TypeMismatchException(context,"String_Node_Str" + name + "String_Node_Str"+ overload.id.originalName());
      }
      formalArgType=abstractInputs.get(i);
      argExprType=kwArgTypes.get(name);
      if (argExprType != null) {
        unmatchedKwArgs.remove(name);
      }
    }
    matched[i]=new MatchedArg(name,formalArgType,argExprType);
  }
  if (unmatchedKwArgs.size() > 0) {
    throw new TypeMismatchException(context,"String_Node_Str" + "String_Node_Str" + overload.id.originalName() + "String_Node_Str"+ unmatchedKwArgs);
  }
  return Arrays.asList(matched);
}