if (lhsType_.getType() == T_TOP || lhsType_.getType() == T_BOTTOM || rhsType_.getType() == T_TOP
|| rhsType_.getType() == T_BOTTOM) {
return;
}
InvokeInstruction inv = (InvokeInstruction) handle.getInstruction();
MethodAnnotation calledMethodAnnotation = getMethodCalledAnnotation(cpg, inv);
boolean looksLikeTestCase = TestCaseDetector.likelyTestCase(XFactory.createXMethod(methodGen));
int priorityModifier = 0;
if (looksLikeTestCase) {
priorityModifier = 1;
}
if (rhsType_.getType() == T_NULL) {
// A literal null value was passed directly to equals().
if (!looksLikeTestCase) {
try {
IsNullValueDataflow isNullDataflow = classContext.getIsNullValueDataflow(method);
IsNullValueFrame isNullFrame = isNullDataflow.getFactAtLocation(location);
BugAnnotation a = BugInstance.getSourceForTopStackValue(classContext, method, location);
int priority = NORMAL_PRIORITY;
if (a instanceof FieldAnnotation && ((FieldAnnotation) a).isStatic()) {
priority = LOW_PRIORITY;
}
if (isNullFrame.isValid() && isNullFrame.getTopValue().isDefinitelyNull()) {
String type = "EC_NULL_ARG";
if (calledMethodAnnotation != null && calledMethodAnnotation.isStatic()){
type = "DMI_DOH";
priority = LOW_PRIORITY;
}
BugInstance bug = new BugInstance(this, type, priority + priorityModifier).addClassAndMethod(methodGen, sourceFile)
.addOptionalAnnotation(calledMethodAnnotation);
if (type.equals("DMI_DOH")) {
bug.addString("Use \"== null\" to check for a value being null");
}
bugAccumulator.accumulateBug(
bug,
SourceLineAnnotation.fromVisitedInstruction(this.classContext, methodGen, sourceFile,
location.getHandle()));
}
} catch (CFGBuilderException e) {
AnalysisContext.logError("Error getting null value analysis", e);
}
}
return;
} 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.
return;
} else if (!(lhsType_ instanceof ReferenceType) || !(rhsType_ instanceof ReferenceType)) {
bugReporter.logError("equals() used to compare non-object type(s) " + lhsType_ + " and " + rhsType_ + " in "
+ SignatureConverter.convertMethodSignature(methodGen) + " at " + location.getHandle());
return;
}
IncompatibleTypes result = IncompatibleTypes.getPriorityForAssumingCompatible(lhsType_, rhsType_);
if (lhsType_ instanceof ArrayType && rhsType_ instanceof ArrayType) {
String pattern = "EC_BAD_ARRAY_COMPARE";
IncompatibleTypes result2 = IncompatibleTypes.getPriorityForAssumingCompatible(lhsType_, rhsType_, true);
if (result2.getPriority() <= Priorities.NORMAL_PRIORITY) {
pattern = "EC_INCOMPATIBLE_ARRAY_COMPARE";
} else if (calledMethodAnnotation != null && calledMethodAnnotation.getClassName().equals("org.testng.Assert")) {
return;
}
bugAccumulator.accumulateBug(new BugInstance(this, pattern, NORMAL_PRIORITY).addClassAndMethod(methodGen, sourceFile)
.addFoundAndExpectedType(rhsType_, lhsType_)
.addSomeSourceForTopTwoStackValues(classContext, method, location)