Program: 27264
Project: 27264
Buggy source:
private EnvTypePair analyzePropAccessFwd(Node receiver,String pname,TypeEnv inEnv,JSType requiredType,JSType specializedType){
  QualifiedName propQname=new QualifiedName(pname);
  Node propAccessNode=receiver.getParent();
  EnvTypePair pair;
  JSType reqObjType=pickReqObjType(propAccessNode);
  JSType recvReqType, recvSpecType;
  if ((NodeUtil.isPropertyTest(compiler,propAccessNode) && !specializedType.isFalseOrFalsy()) || (NodeUtil.isPropertyAbsenceTest(propAccessNode) && !specializedType.isTrueOrTruthy()) || specializedType.isTrueOrTruthy()) {
    recvReqType=reqObjType;
    pair=analyzeExprFwd(receiver,inEnv,recvReqType);
    JSType subtypeWithProp=pair.type.findSubtypeWithProp(propQname);
    if (subtypeWithProp.isBottom()) {
      recvSpecType=reqObjType;
    }
 else {
      recvSpecType=subtypeWithProp;
    }
    if (specializedType.isTrueOrTruthy()) {
      recvSpecType=recvSpecType.withLoose().withProperty(propQname,specializedType);
    }
 else {
      recvSpecType=recvSpecType.withProperty(propQname,specializedType);
    }
  }
 else   if (specializedType.isFalseOrFalsy()) {
    recvReqType=recvSpecType=reqObjType;
  }
 else {
    recvReqType=reqObjType.withProperty(propQname,requiredType);
    recvSpecType=reqObjType.withProperty(propQname,specializedType);
  }
  pair=analyzeExprFwd(receiver,inEnv,recvReqType,recvSpecType);
  pair=mayWarnAboutNullableReferenceAndTighten(receiver,pair.type,recvSpecType,pair.env);
  JSType recvType=pair.type.autobox();
  if (recvType.isUnknown() || recvType.isTrueOrTruthy()) {
    mayWarnAboutInexistentProp(propAccessNode,recvType,propQname);
    return new EnvTypePair(pair.env,requiredType);
  }
  if (mayWarnAboutNonObject(receiver,recvType,specializedType)) {
    return new EnvTypePair(pair.env,requiredType);
  }
  FunctionType ft=recvType.getFunTypeIfSingletonObj();
  if (ft != null && (pname.equals("String_Node_Str") || pname.equals("String_Node_Str"))) {
    if (ft.isAbstract()) {
      String funName=receiver.isQualifiedName() ? receiver.getQualifiedName() : "String_Node_Str";
      warnings.add(JSError.make(propAccessNode,ABSTRACT_SUPER_METHOD_NOT_CALLABLE,funName));
    }
    return new EnvTypePair(pair.env,pname.equals("String_Node_Str") ? commonTypes.fromFunctionType(ft.transformByCallProperty()) : commonTypes.fromFunctionType(ft.transformByApplyProperty()));
  }
  if (this.convention.isSuperClassReference(pname)) {
    if (ft != null && ft.isUniqueConstructor()) {
      JSType result=ft.getSuperPrototype();
      pair.type=result != null ? result : UNDEFINED;
      return pair;
    }
  }
  if (propAccessNode.isGetProp() && mayWarnAboutDictPropAccess(receiver,recvType)) {
    return new EnvTypePair(pair.env,requiredType);
  }
  if (recvType.isTop()) {
    recvType=TOP_OBJECT;
  }
  if (propAccessNode.getParent().isDelProp() && recvType.hasConstantProp(propQname)) {
    warnings.add(JSError.make(propAccessNode.getParent(),CONST_PROPERTY_DELETED,pname));
  }
  QualifiedName getterPname=new QualifiedName(JSType.createGetterPropName(pname));
  if (recvType.hasProp(getterPname)) {
    return new EnvTypePair(pair.env,recvType.getProp(getterPname));
  }
  JSType resultType=recvType.getProp(propQname);
  if (resultType != null && resultType.isBottom()) {
    warnings.add(JSError.make(propAccessNode,BOTTOM_PROP,pname,recvType.toString()));
    return new EnvTypePair(pair.env,UNKNOWN);
  }
  if (!propAccessNode.getParent().isExprResult() && !specializedType.isTrueOrTruthy() && !specializedType.isFalseOrFalsy()&& !recvType.mayBeDict()&& !mayWarnAboutInexistentProp(propAccessNode,recvType,propQname)&& recvType.hasProp(propQname)&& !resultType.isSubtypeOf(requiredType)&& tightenPropertyTypeAndDontWarn(receiver.isName() ? receiver.getString() : null,propAccessNode,recvType,recvType.getDeclaredProp(propQname),resultType,requiredType)) {
    resultType=resultType.specialize(requiredType);
    LValueResultFwd lvr=analyzeLValueFwd(propAccessNode,inEnv,resultType);
    TypeEnv updatedEnv=updateLvalueTypeInEnv(lvr.env,propAccessNode,lvr.ptr,resultType);
    return new EnvTypePair(updatedEnv,resultType);
  }
  if (resultType == null) {
    resultType=UNKNOWN;
  }
  return new EnvTypePair(pair.env,resultType);
}

Fixed version (ground truth):
private EnvTypePair analyzePropAccessFwd(Node receiver,String pname,TypeEnv inEnv,JSType requiredType,JSType specializedType){
  QualifiedName propQname=new QualifiedName(pname);
  Node propAccessNode=receiver.getParent();
  EnvTypePair pair;
  JSType reqObjType=pickReqObjType(propAccessNode);
  JSType recvReqType;
  JSType recvSpecType;
  if ((NodeUtil.isPropertyTest(compiler,propAccessNode) && !specializedType.isFalseOrFalsy()) || (NodeUtil.isPropertyAbsenceTest(propAccessNode) && !specializedType.isTrueOrTruthy()) || specializedType.isTrueOrTruthy()) {
    recvReqType=reqObjType;
    pair=analyzeExprFwd(receiver,inEnv,recvReqType);
    JSType subtypeWithProp=pair.type.findSubtypeWithProp(propQname);
    if (subtypeWithProp.isBottom()) {
      recvSpecType=reqObjType;
    }
 else {
      recvSpecType=subtypeWithProp;
    }
    if (specializedType.isTrueOrTruthy()) {
      recvSpecType=recvSpecType.withLoose().withProperty(propQname,specializedType);
    }
 else {
      recvSpecType=recvSpecType.withProperty(propQname,specializedType);
    }
  }
 else   if (specializedType.isFalseOrFalsy()) {
    recvReqType=recvSpecType=reqObjType;
  }
 else {
    recvReqType=reqObjType.withProperty(propQname,requiredType);
    recvSpecType=reqObjType.withProperty(propQname,specializedType);
  }
  pair=analyzeExprFwd(receiver,inEnv,recvReqType,recvSpecType);
  pair=mayWarnAboutNullableReferenceAndTighten(receiver,pair.type,recvSpecType,pair.env);
  JSType recvType=pair.type.autobox();
  if (recvType.isUnknown() || recvType.isTrueOrTruthy()) {
    mayWarnAboutInexistentProp(propAccessNode,recvType,propQname);
    return new EnvTypePair(pair.env,requiredType);
  }
  if (mayWarnAboutNonObject(receiver,recvType,specializedType)) {
    return new EnvTypePair(pair.env,requiredType);
  }
  FunctionType ft=recvType.getFunTypeIfSingletonObj();
  if (ft != null && (pname.equals("String_Node_Str") || pname.equals("String_Node_Str"))) {
    if (ft.isAbstract()) {
      String funName=receiver.isQualifiedName() ? receiver.getQualifiedName() : "String_Node_Str";
      warnings.add(JSError.make(propAccessNode,ABSTRACT_SUPER_METHOD_NOT_CALLABLE,funName));
    }
    return new EnvTypePair(pair.env,pname.equals("String_Node_Str") ? commonTypes.fromFunctionType(ft.transformByCallProperty()) : commonTypes.fromFunctionType(ft.transformByApplyProperty()));
  }
  if (this.convention.isSuperClassReference(pname)) {
    if (ft != null && ft.isUniqueConstructor()) {
      JSType result=ft.getSuperPrototype();
      pair.type=result != null ? result : UNDEFINED;
      return pair;
    }
  }
  if (propAccessNode.isGetProp() && mayWarnAboutDictPropAccess(receiver,recvType)) {
    return new EnvTypePair(pair.env,requiredType);
  }
  if (recvType.isTop()) {
    recvType=TOP_OBJECT;
  }
  if (propAccessNode.getParent().isDelProp() && recvType.hasConstantProp(propQname)) {
    warnings.add(JSError.make(propAccessNode.getParent(),CONST_PROPERTY_DELETED,pname));
  }
  QualifiedName getterPname=new QualifiedName(JSType.createGetterPropName(pname));
  if (recvType.hasProp(getterPname)) {
    return new EnvTypePair(pair.env,recvType.getProp(getterPname));
  }
  JSType resultType=recvType.getProp(propQname);
  if (resultType != null && resultType.isBottom()) {
    warnings.add(JSError.make(propAccessNode,BOTTOM_PROP,pname,recvType.toString()));
    return new EnvTypePair(pair.env,UNKNOWN);
  }
  if (!propAccessNode.getParent().isExprResult() && !specializedType.isTrueOrTruthy() && !specializedType.isFalseOrFalsy()&& !recvType.mayBeDict()&& !mayWarnAboutInexistentProp(propAccessNode,recvType,propQname)&& recvType.hasProp(propQname)&& !resultType.isSubtypeOf(requiredType)&& tightenPropertyTypeAndDontWarn(receiver.isName() ? receiver.getString() : null,propAccessNode,recvType,recvType.getDeclaredProp(propQname),resultType,requiredType)) {
    resultType=resultType.specialize(requiredType);
    LValueResultFwd lvr=analyzeLValueFwd(propAccessNode,inEnv,resultType);
    TypeEnv updatedEnv=updateLvalueTypeInEnv(lvr.env,propAccessNode,lvr.ptr,resultType);
    return new EnvTypePair(updatedEnv,resultType);
  }
  if (resultType == null) {
    resultType=UNKNOWN;
  }
  return new EnvTypePair(pair.env,resultType);
}