# HG changeset patch # User Doug Simon # Date 1417426145 -3600 # Node ID 1b918c6ff5eb920cb4e2ffc3a4a03a959e93de63 # Parent d24328ea36a7ee0a96634f3f1a1eeb6460a536c7 allow == when one of the variables is the receiver in equals() diff -r d24328ea36a7 -r 1b918c6ff5eb graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Mon Dec 01 10:00:33 2014 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Mon Dec 01 10:29:05 2014 +0100 @@ -65,20 +65,47 @@ return node.isConstant() && node.isNullConstant(); } + private static boolean isEqualsMethod(ResolvedJavaMethod method) { + if (method.getName().equals("equals")) { + Signature sig = method.getSignature(); + if (sig.getReturnKind() == Kind.Boolean) { + if (sig.getParameterCount(false) == 1) { + ResolvedJavaType ptype = (ResolvedJavaType) sig.getParameterType(0, method.getDeclaringClass()); + if (ptype.isJavaLangObject()) { + return true; + } + + } + } + } + return false; + } + + private static boolean isThisParameter(ValueNode node) { + return node instanceof ParameterNode && ((ParameterNode) node).index() == 0; + } + /** * Checks whether the type of {@code x} is assignable to the restricted type and that {@code y} * is not a null constant. */ - private boolean isIllegalUsage(ValueNode x, ValueNode y, MetaAccessProvider metaAccess) { - return isAssignableToRestrictedType(x, metaAccess) && !isNullConstant(y); + private boolean isIllegalUsage(ResolvedJavaMethod method, ValueNode x, ValueNode y, MetaAccessProvider metaAccess) { + if (isAssignableToRestrictedType(x, metaAccess) && !isNullConstant(y)) { + if (isEqualsMethod(method) && isThisParameter(x) || isThisParameter(y)) { + return false; + } + return true; + } + return false; } @Override protected boolean verify(StructuredGraph graph, PhaseContext context) { for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) { // bail out if we compare an object of type klass with == or != (except null checks) - if (isIllegalUsage(cn.getX(), cn.getY(), context.getMetaAccess()) || isIllegalUsage(cn.getY(), cn.getX(), context.getMetaAccess())) { - throw new VerificationError("Verification of " + restrictedClass.getName() + " usage failed: Comparing " + cn.getX() + " and " + cn.getY() + " in " + graph.method() + + ResolvedJavaMethod method = graph.method(); + if (isIllegalUsage(method, cn.getX(), cn.getY(), context.getMetaAccess()) || isIllegalUsage(method, cn.getY(), cn.getX(), context.getMetaAccess())) { + throw new VerificationError("Verification of " + restrictedClass.getName() + " usage failed: Comparing " + cn.getX() + " and " + cn.getY() + " in " + method + " must use .equals() for object equality, not '==' or '!='"); } }