.addClass(lhsType_.getSignature()).describe("CLASS_REFTYPE") .addClass(rhsType_.getSignature()).describe("CLASS_REFTYPE")
.addType(originalLhsType.getSignature()) .addType(originalRhsType.getSignature())
	private void checkEqualsComparison(			Location location,			JavaClass jclass,			MethodGen methodGen,			TypeDataflow typeDataflow) throws DataflowAnalysisException {		InstructionHandle handle = location.getHandle();		String sourceFile = jclass.getSourceFileName();		TypeFrame frame = typeDataflow.getFactAtLocation(location);		if (frame.getStackDepth() < 2)			throw new DataflowAnalysisException("Stack underflow", methodGen, handle);		int numSlots = frame.getNumSlots();		Type lhsType_ = frame.getValue(numSlots - 2);		Type rhsType_ = frame.getValue(numSlots - 1);			// Ignore top and bottom values		if (lhsType_.getType() == T_TOP || lhsType_.getType() == T_BOTTOM		        || rhsType_.getType() == T_TOP || rhsType_.getType() == T_BOTTOM)			return;		if (!(lhsType_ instanceof ReferenceType) || !(rhsType_ instanceof ReferenceType)) {			if (rhsType_.getType() == T_NULL) {				boolean isTestCase = false;				Method method = methodGen.getMethod();				if (method.getName().startsWith("test") && method.isPublic() && method.getSignature().equals("()V")						|| methodGen.getClassName().endsWith("Test"))					isTestCase = true;				// A literal null value was passed directly to equals().				if (!isTestCase)					bugReporter.reportBug(new BugInstance(this, "EC_NULL_ARG", NORMAL_PRIORITY)				        .addClassAndMethod(methodGen, sourceFile)				        .addSourceLine(this.classContext, methodGen, sourceFile, location.getHandle()));			} else if (lhsType_.getType() == T_NULL) {				// Hmm...in this case, equals() is being invoked on				// a literal null value.  This is really the				// purview of FindNullDeref.  So, we'll just do nothing.			} else {				bugReporter.logError("equals() used to compare non-object type(s) " +				        lhsType_ + " and " + rhsType_ +				        " in " +				        SignatureConverter.convertMethodSignature(methodGen) +				        " at " + location.getHandle());			}			return;		}				if (lhsType_ instanceof ArrayType && rhsType_ instanceof ArrayType) {			bugReporter.reportBug(new BugInstance(this, "EC_BAD_ARRAY_COMPARE", NORMAL_PRIORITY)			        .addClassAndMethod(methodGen, sourceFile)			        .addClass(lhsType_.getSignature()).describe("CLASS_REFTYPE")			        .addClass(rhsType_.getSignature()).describe("CLASS_REFTYPE")			        .addSourceLine(this.classContext, methodGen, sourceFile, location.getHandle())			         );		do {			lhsType_ = ((ArrayType)lhsType_).getElementType();			rhsType_ = ((ArrayType)rhsType_).getElementType();		} while  (lhsType_ instanceof ArrayType && rhsType_ instanceof ArrayType);		}				if (lhsType_ instanceof ArrayType) {			int priority = HIGH_PRIORITY;			if (rhsType_.equals(ObjectType.OBJECT)) priority = LOW_PRIORITY;			bugReporter.reportBug(new BugInstance(this, "EC_ARRAY_AND_NONARRAY", priority)			        .addClassAndMethod(methodGen, sourceFile)			        .addClass(lhsType_.getSignature()).describe("CLASS_REFTYPE")			        .addClass(rhsType_.getSignature()).describe("CLASS_REFTYPE")			        .addSourceLine(this.classContext, methodGen, sourceFile, location.getHandle())			         );		}		if (rhsType_ instanceof ArrayType) {			int priority = HIGH_PRIORITY;			if (lhsType_.equals(ObjectType.OBJECT)) priority = LOW_PRIORITY;			bugReporter.reportBug(new BugInstance(this, "EC_ARRAY_AND_NONARRAY", priority)			        .addClassAndMethod(methodGen, sourceFile)			        .addClass(rhsType_.getSignature()).describe("CLASS_REFTYPE")			        .addClass(lhsType_.getSignature()).describe("CLASS_REFTYPE")			        .addSourceLine(this.classContext, methodGen, sourceFile, location.getHandle())			         );		}		if (lhsType_.equals(rhsType_))			return;		// For now, ignore the case where either reference is not		// of an object type.  (It could be either an array or null.)		if (!(lhsType_ instanceof ObjectType) || !(rhsType_ instanceof ObjectType))			return;		ObjectType lhsType = (ObjectType) lhsType_;		ObjectType rhsType = (ObjectType) rhsType_;		int priority = LOW_PRIORITY + 1;		String bugType = "EC_UNRELATED_TYPES";		// See if the types are related by inheritance.		try {			if (!Hierarchy.isSubtype(lhsType, rhsType) && !Hierarchy.isSubtype(rhsType, lhsType)) {				AnalysisContext analysisContext = AnalysisContext.currentAnalysisContext();								// Look up the classes				JavaClass lhsClass = analysisContext.lookupClass(lhsType.getClassName());				JavaClass rhsClass = analysisContext.lookupClass(rhsType.getClassName());				if (!lhsClass.isInterface() && !rhsClass.isInterface()) {					// Both are class types, and therefore there is no possible way					// the compared objects can have the same runtime type.					priority = HIGH_PRIORITY;				} else {					/*					if (DEBUG) {						System.out.println("Subtypes of " + lhsClass.getClassName() + " are " +								classSetToString(analysisContext.getSubtypes().getTransitiveSubtypes(lhsClass)));						System.out.println("Subtypes of " + rhsClass.getClassName() + " are " +								classSetToString(analysisContext.getSubtypes().getTransitiveSubtypes(rhsClass)));					}					*/										// Look up the common subtypes of the two types.  If the					// intersection does not contain at least one instantiable class,					// then issue a warning of the appropriate type.					Set<JavaClass> commonSubtypes =						analysisContext.getSubtypes().getTransitiveCommonSubtypes(lhsClass, rhsClass);										if (!containsAtLeastOneInstantiableClass(commonSubtypes)) {						priority = HIGH_PRIORITY;						bugType = (lhsClass.isInterface() && rhsClass.isInterface())							? "EC_UNRELATED_INTERFACES" : "EC_UNRELATED_CLASS_AND_INTERFACE";					}				}			}		} catch (ClassNotFoundException e) {			bugReporter.reportMissingClass(e);			return;		}		if (methodGen.getName().startsWith("test") && methodGen.getSignature().equals("()V")) {			try {				if (Hierarchy.isSubtype(methodGen.getClassName(), "junit.framework.TestCase"))					priority+=2;			} catch (ClassNotFoundException e) { priority+=2; }			}				if (priority <= LOW_PRIORITY) {			bugReporter.reportBug(new BugInstance(this, bugType, priority)			        .addClassAndMethod(methodGen, sourceFile)			        .addClass(lhsType.getClassName()).describe("CLASS_REFTYPE")			        .addClass(rhsType.getClassName()).describe("CLASS_REFTYPE")			        .addSourceLine(this.classContext, methodGen, sourceFile, location.getHandle())			        );		}	}