Program: 82701
Project: 82701
Buggy source:
/** 
 * This method determines whether a type can be serialized by GWT. To do so, it must traverse all subtypes as well as all field types of those types, transitively. It returns a boolean indicating whether this type or any of its subtypes are instantiable. As a side effect, all types needed--plus some--to serialize this type are accumulated in   {@link #typeToTypeInfoComputed}. The method is exposed using default access to enable testing.
 */
final boolean checkTypeInstantiable(TreeLogger logger,JType type,boolean isSpeculative,final Path path){
  assert(type != null);
  if (type.isPrimitive() != null) {
    return true;
  }
  assert(type instanceof JClassType);
  JClassType classType=(JClassType)type;
  TreeLogger localLogger=logger.branch(TreeLogger.DEBUG,classType.getParameterizedQualifiedSourceName(),null);
  if (!isAllowedByFilter(localLogger,classType,isSpeculative)) {
    return false;
  }
  JTypeParameter isTypeParameter=classType.isTypeParameter();
  if (isTypeParameter != null) {
    if (typeParametersInRootTypes.contains(isTypeParameter)) {
      return checkTypeInstantiable(localLogger,isTypeParameter.getFirstBound(),isSpeculative,path);
    }
    return true;
  }
  JWildcardType isWildcard=classType.isWildcard();
  if (isWildcard != null) {
    boolean success=true;
    for (    JClassType bound : isWildcard.getUpperBounds()) {
      success&=checkTypeInstantiable(localLogger,bound,isSpeculative,path);
    }
    return success;
  }
  TypeInfoComputed tic=getTypeInfoComputed(classType,path);
  if (tic.isPendingInstantiable()) {
    return true;
  }
 else   if (tic.isDone()) {
    return tic.hasInstantiableSubtypes();
  }
  tic.setPendingInstantiable();
  JArrayType isArray=classType.isArray();
  if (isArray != null) {
    JType leafType=isArray.getLeafType();
    JTypeParameter isLeafTypeParameter=leafType.isTypeParameter();
    if (isLeafTypeParameter != null && !typeParametersInRootTypes.contains(isLeafTypeParameter)) {
      tic.setInstantiable(false);
      tic.setInstantiableSubytpes(true);
      return true;
    }
    boolean succeeded=checkArrayInstantiable(localLogger,isArray,isSpeculative,path);
    if (succeeded) {
      JClassType leafClass=leafType.isClassOrInterface();
      if (leafClass != null) {
        JClassType[] leafSubtypes=leafClass.getErasedType().getSubtypes();
        for (        JClassType leafSubtype : leafSubtypes) {
          JArrayType covariantArray=getArrayType(typeOracle,isArray.getRank(),leafSubtype);
          checkTypeInstantiable(localLogger,covariantArray,true,path);
        }
      }
    }
    tic.setInstantiable(succeeded);
    return succeeded;
  }
  if (classType == typeOracle.getJavaLangObject()) {
    localLogger.branch(getLogLevel(isSpeculative),"String_Node_Str",null);
    tic.setInstantiable(false);
    return false;
  }
  if (classType.isRawType() != null) {
    TreeLogger rawTypeLogger=localLogger.branch(TreeLogger.DEBUG,"String_Node_Str" + classType.getQualifiedSourceName() + "String_Node_Str",null);
    if (classType.isAssignableTo(collectionClass) || classType.isAssignableTo(mapClass)) {
      checkAllSubtypesOfObject(rawTypeLogger,path);
    }
  }
  JClassType originalType=(JClassType)type;
  JRealClassType baseType;
  if (type.isRawType() != null) {
    baseType=type.isRawType().getBaseType();
  }
 else   if (type.isParameterized() != null) {
    baseType=type.isParameterized().getBaseType();
  }
 else {
    baseType=(JRealClassType)originalType;
  }
  if (isSpeculative && tic.isDirectlySerializable()) {
    isSpeculative=false;
  }
  boolean isInstantiable=checkTypeInstantiableNoSubtypes(localLogger,baseType,isSpeculative,path);
  JClassType[] typeArgs=NO_JCLASSES;
  JParameterizedType isParameterized=originalType.isParameterized();
  JGenericType baseAsGenericType=baseType.isGenericType();
  if (isParameterized != null) {
    typeArgs=isParameterized.getTypeArgs();
  }
 else   if (baseAsGenericType != null) {
    List<JClassType> arguments=new ArrayList<JClassType>();
    for (    JTypeParameter typeParameter : baseAsGenericType.getTypeParameters()) {
      arguments.add(typeParameter.getFirstBound());
    }
    typeArgs=arguments.toArray(NO_JCLASSES);
  }
  boolean parametersOkay=true;
  JRawType isRaw=originalType.isRawType();
  if (isParameterized != null || isRaw != null) {
    assert(baseAsGenericType != null);
    int numDeclaredParams=baseAsGenericType.getTypeParameters().length;
    if (numDeclaredParams == typeArgs.length) {
      for (int i=0; i < numDeclaredParams; ++i) {
        JClassType typeArg=typeArgs[i];
        parametersOkay&=checkTypeArgument(localLogger,baseAsGenericType,i,typeArg,isSpeculative,path);
      }
    }
 else {
      for (int i=0; i < numDeclaredParams; ++i) {
        JClassType typeArg=typeArgs[i];
        parametersOkay&=checkTypeInstantiable(localLogger,typeArg,isSpeculative,path);
      }
    }
  }
  isInstantiable&=parametersOkay;
  boolean anySubtypes=false;
  if (parametersOkay) {
    JClassType[] subtypes=baseType.getSubtypes();
    if (subtypes.length > 0) {
      TreeLogger subtypesLogger=localLogger.branch(TreeLogger.DEBUG,"String_Node_Str",null);
      for (      JClassType subtype : subtypes) {
        TreeLogger subtypeLogger=subtypesLogger.branch(TreeLogger.DEBUG,subtype.getParameterizedQualifiedSourceName(),null);
        Path subtypePath=createSubtypePath(path,subtype,originalType);
        boolean subInstantiable=checkTypeInstantiableNoSubtypes(subtypeLogger,subtype,true,subtypePath);
        JGenericType genericSub=subtype.isGenericType();
        if (genericSub != null) {
          TreeLogger paramsLogger=subtypeLogger.branch(TreeLogger.DEBUG,"String_Node_Str" + genericSub.getParameterizedQualifiedSourceName() + "String_Node_Str");
          Map<JTypeParameter,Set<JTypeParameter>> subParamsConstrainedBy=subParamsConstrainedBy(baseType,genericSub);
          for (int i=0; i < genericSub.getTypeParameters().length; i++) {
            JTypeParameter param=genericSub.getTypeParameters()[i];
            TreeLogger paramLogger=paramsLogger.branch(TreeLogger.DEBUG,"String_Node_Str" + param.getParameterizedQualifiedSourceName() + "String_Node_Str");
            Set<JTypeParameter> constBy=subParamsConstrainedBy.get(param);
            if (constBy == null) {
              subInstantiable&=checkTypeArgument(paramLogger,genericSub,i,param.getFirstBound(),true,path);
            }
 else {
              boolean paramOK=false;
              for (              JTypeParameter constrained : constBy) {
                paramOK|=checkTypeArgument(paramLogger,genericSub,i,typeArgs[constrained.getOrdinal()],true,path);
              }
              subInstantiable&=paramOK;
            }
          }
        }
 else {
          if (subInstantiable && isParameterized != null) {
            HashSet<JTypeParameter> typeParamsInQueryType=new HashSet<JTypeParameter>();
            recordTypeParametersIn(isParameterized,typeParamsInQueryType);
            if (typeParamsInQueryType.isEmpty()) {
              if (!isParameterized.isAssignableFrom(subtype)) {
                subtypeLogger.log(TreeLogger.DEBUG,"String_Node_Str" + subtype.getParameterizedQualifiedSourceName() + "String_Node_Str"+ isParameterized.getParameterizedQualifiedSourceName()+ "String_Node_Str");
                subInstantiable=false;
              }
            }
          }
        }
        if (subInstantiable) {
          getTypeInfoComputed(subtype,path).setInstantiable(true);
          anySubtypes=true;
        }
      }
    }
  }
  anySubtypes|=isInstantiable;
  tic.setInstantiable(isInstantiable);
  tic.setInstantiableSubytpes(anySubtypes);
  if (!anySubtypes && !isSpeculative) {
    localLogger.branch(getLogLevel(isSpeculative),"String_Node_Str" + classType.getParameterizedQualifiedSourceName() + "String_Node_Str",null);
  }
  return tic.hasInstantiableSubtypes();
}

Fixed version (ground truth):
/** 
 * This method determines whether a type can be serialized by GWT. To do so, it must traverse all subtypes as well as all field types of those types, transitively. It returns a boolean indicating whether this type or any of its subtypes are instantiable. As a side effect, all types needed--plus some--to serialize this type are accumulated in   {@link #typeToTypeInfoComputed}. The method is exposed using default access to enable testing.
 */
final boolean checkTypeInstantiable(TreeLogger logger,JType type,boolean isSpeculative,final Path path){
  assert(type != null);
  if (type.isPrimitive() != null) {
    return true;
  }
  assert(type instanceof JClassType);
  JClassType classType=(JClassType)type;
  TreeLogger localLogger=logger.branch(TreeLogger.DEBUG,classType.getParameterizedQualifiedSourceName(),null);
  if (!isAllowedByFilter(localLogger,classType,isSpeculative)) {
    return false;
  }
  JTypeParameter isTypeParameter=classType.isTypeParameter();
  if (isTypeParameter != null) {
    if (typeParametersInRootTypes.contains(isTypeParameter)) {
      return checkTypeInstantiable(localLogger,isTypeParameter.getFirstBound(),isSpeculative,path);
    }
    return true;
  }
  JWildcardType isWildcard=classType.isWildcard();
  if (isWildcard != null) {
    boolean success=true;
    for (    JClassType bound : isWildcard.getUpperBounds()) {
      success&=checkTypeInstantiable(localLogger,bound,isSpeculative,path);
    }
    return success;
  }
  TypeInfoComputed tic=getTypeInfoComputed(classType,path);
  if (tic.isPendingInstantiable()) {
    return true;
  }
 else   if (tic.isDone()) {
    return tic.hasInstantiableSubtypes();
  }
  tic.setPendingInstantiable();
  JArrayType isArray=classType.isArray();
  if (isArray != null) {
    JType leafType=isArray.getLeafType();
    JTypeParameter isLeafTypeParameter=leafType.isTypeParameter();
    if (isLeafTypeParameter != null && !typeParametersInRootTypes.contains(isLeafTypeParameter)) {
      tic.setInstantiable(false);
      tic.setInstantiableSubytpes(true);
      return true;
    }
    boolean succeeded=checkArrayInstantiable(localLogger,isArray,isSpeculative,path);
    if (succeeded) {
      JClassType leafClass=leafType.isClassOrInterface();
      if (leafClass != null) {
        JClassType[] leafSubtypes=leafClass.getErasedType().getSubtypes();
        for (        JClassType leafSubtype : leafSubtypes) {
          if (leafSubtype.isRawType() != null) {
            JGenericType leafGenericSub=leafSubtype.isRawType().getBaseType();
            leafSubtype=typeOracle.getParameterizedType(leafGenericSub,leafGenericSub.getTypeParameters());
          }
          if (!isAccessibleToClassesInSamePackage(leafSubtype)) {
            continue;
          }
          JArrayType covariantArray=getArrayType(typeOracle,isArray.getRank(),leafSubtype);
          checkTypeInstantiable(localLogger,covariantArray,true,path);
        }
      }
    }
    tic.setInstantiable(succeeded);
    return succeeded;
  }
  if (classType == typeOracle.getJavaLangObject()) {
    localLogger.branch(getLogLevel(isSpeculative),"String_Node_Str",null);
    tic.setInstantiable(false);
    return false;
  }
  if (classType.isRawType() != null) {
    TreeLogger rawTypeLogger=localLogger.branch(TreeLogger.DEBUG,"String_Node_Str" + classType.getQualifiedSourceName() + "String_Node_Str",null);
    if (classType.isAssignableTo(collectionClass) || classType.isAssignableTo(mapClass)) {
      checkAllSubtypesOfObject(rawTypeLogger,path);
    }
  }
  JClassType originalType=(JClassType)type;
  JRealClassType baseType;
  if (type.isRawType() != null) {
    baseType=type.isRawType().getBaseType();
  }
 else   if (type.isParameterized() != null) {
    baseType=type.isParameterized().getBaseType();
  }
 else {
    baseType=(JRealClassType)originalType;
  }
  if (isSpeculative && tic.isDirectlySerializable()) {
    isSpeculative=false;
  }
  boolean isInstantiable=checkTypeInstantiableNoSubtypes(localLogger,baseType,isSpeculative,path);
  JClassType[] typeArgs=NO_JCLASSES;
  JParameterizedType isParameterized=originalType.isParameterized();
  JGenericType baseAsGenericType=baseType.isGenericType();
  if (isParameterized != null) {
    typeArgs=isParameterized.getTypeArgs();
  }
 else   if (baseAsGenericType != null) {
    List<JClassType> arguments=new ArrayList<JClassType>();
    for (    JTypeParameter typeParameter : baseAsGenericType.getTypeParameters()) {
      arguments.add(typeParameter.getFirstBound());
    }
    typeArgs=arguments.toArray(NO_JCLASSES);
  }
  boolean parametersOkay=true;
  JRawType isRaw=originalType.isRawType();
  if (isParameterized != null || isRaw != null) {
    assert(baseAsGenericType != null);
    int numDeclaredParams=baseAsGenericType.getTypeParameters().length;
    if (numDeclaredParams == typeArgs.length) {
      for (int i=0; i < numDeclaredParams; ++i) {
        JClassType typeArg=typeArgs[i];
        parametersOkay&=checkTypeArgument(localLogger,baseAsGenericType,i,typeArg,isSpeculative,path);
      }
    }
 else {
      for (int i=0; i < numDeclaredParams; ++i) {
        JClassType typeArg=typeArgs[i];
        parametersOkay&=checkTypeInstantiable(localLogger,typeArg,isSpeculative,path);
      }
    }
  }
  isInstantiable&=parametersOkay;
  boolean anySubtypes=false;
  if (parametersOkay) {
    JClassType[] subtypes=baseType.getSubtypes();
    if (subtypes.length > 0) {
      TreeLogger subtypesLogger=localLogger.branch(TreeLogger.DEBUG,"String_Node_Str",null);
      for (      JClassType subtype : subtypes) {
        TreeLogger subtypeLogger=subtypesLogger.branch(TreeLogger.DEBUG,subtype.getParameterizedQualifiedSourceName(),null);
        Path subtypePath=createSubtypePath(path,subtype,originalType);
        boolean subInstantiable=checkTypeInstantiableNoSubtypes(subtypeLogger,subtype,true,subtypePath);
        if (!subInstantiable) {
          continue;
        }
        JGenericType genericSub=subtype.isGenericType();
        if (genericSub != null) {
          TreeLogger paramsLogger=subtypeLogger.branch(TreeLogger.DEBUG,"String_Node_Str" + genericSub.getParameterizedQualifiedSourceName() + "String_Node_Str");
          Map<JTypeParameter,Set<JTypeParameter>> subParamsConstrainedBy=subParamsConstrainedBy(baseType,genericSub);
          for (int i=0; i < genericSub.getTypeParameters().length; i++) {
            JTypeParameter param=genericSub.getTypeParameters()[i];
            TreeLogger paramLogger=paramsLogger.branch(TreeLogger.DEBUG,"String_Node_Str" + param.getParameterizedQualifiedSourceName() + "String_Node_Str");
            Set<JTypeParameter> constBy=subParamsConstrainedBy.get(param);
            if (constBy == null) {
              subInstantiable&=checkTypeArgument(paramLogger,genericSub,i,param.getFirstBound(),true,path);
            }
 else {
              boolean paramOK=false;
              for (              JTypeParameter constrained : constBy) {
                paramOK|=checkTypeArgument(paramLogger,genericSub,i,typeArgs[constrained.getOrdinal()],true,path);
              }
              subInstantiable&=paramOK;
            }
          }
        }
 else {
          if (isParameterized != null) {
            HashSet<JTypeParameter> typeParamsInQueryType=new HashSet<JTypeParameter>();
            recordTypeParametersIn(isParameterized,typeParamsInQueryType);
            if (typeParamsInQueryType.isEmpty()) {
              if (!isParameterized.isAssignableFrom(subtype)) {
                subtypeLogger.log(TreeLogger.DEBUG,"String_Node_Str" + subtype.getParameterizedQualifiedSourceName() + "String_Node_Str"+ isParameterized.getParameterizedQualifiedSourceName()+ "String_Node_Str");
                subInstantiable=false;
              }
            }
          }
        }
        if (subInstantiable) {
          getTypeInfoComputed(subtype,path).setInstantiable(true);
          anySubtypes=true;
        }
      }
    }
  }
  anySubtypes|=isInstantiable;
  tic.setInstantiable(isInstantiable);
  tic.setInstantiableSubytpes(anySubtypes);
  if (!anySubtypes && !isSpeculative) {
    localLogger.branch(getLogLevel(isSpeculative),"String_Node_Str" + classType.getParameterizedQualifiedSourceName() + "String_Node_Str",null);
  }
  return tic.hasInstantiableSubtypes();
}