diff --git a/src/dmd/expressionsem.d b/src/dmd/expressionsem.d index 48e47cef2508..fe383a72e941 100644 --- a/src/dmd/expressionsem.d +++ b/src/dmd/expressionsem.d @@ -11333,7 +11333,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); } - EXP cmpop; + + EXP cmpop = exp.op; if (auto e = exp.op_overload(sc, &cmpop)) { if (!e.type.isscalar() && e.type.equals(exp.e1.type)) @@ -11343,6 +11344,40 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } if (e.op == EXP.call) { + + if (t1.ty == Tclass && t2.ty == Tclass) + { + // Lower to object.__cmp(e1, e2) + Expression cl = new IdentifierExp(exp.loc, Id.empty); + cl = new DotIdExp(exp.loc, cl, Id.object); + cl = new DotIdExp(exp.loc, cl, Id.__cmp); + cl = cl.expressionSemantic(sc); + + CallExp cexp = cast(CallExp) e; + + auto arguments = new Expressions(); + // Check if op_overload found a better match by calling e2.opCmp(e1) + // If the operands were swapped, then the result must be reversed + // e1.opCmp(e2) == -e2.opCmp(e1) + // cmpop takes care of this + if (exp.op == cmpop) + { + arguments.push(exp.e1); + arguments.push(exp.e2); + } + else + { + // Use better match found by op_overload + arguments.push(exp.e2); + arguments.push(exp.e1); + } + + cl = new CallExp(exp.loc, cl, arguments); + cl = new CmpExp(cmpop, exp.loc, cl, new IntegerExp(0)); + result = cl.expressionSemantic(sc); + return; + } + e = new CmpExp(cmpop, exp.loc, e, IntegerExp.literal!0); e = e.expressionSemantic(sc); } @@ -11350,6 +11385,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } + if (Expression ex = typeCombine(exp, sc)) { result = ex; diff --git a/src/dmd/opover.d b/src/dmd/opover.d index bafeaa332dc2..16ade7c05c6a 100644 --- a/src/dmd/opover.d +++ b/src/dmd/opover.d @@ -853,11 +853,11 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) { // Rewrite (e1 op e2) as e2.opfunc(e1) result = build_overload(e.loc, sc, e.e2, e.e1, m.lastf ? m.lastf : s); + // When reversing operands of comparison operators, + // need to reverse the sense of the op + if (pop) + *pop = reverseRelation(e.op); } - // When reversing operands of comparison operators, - // need to reverse the sense of the op - if (pop) - *pop = reverseRelation(e.op); return; } }