@@ -11333,7 +11333,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
1133311333 return setError ();
1133411334 }
1133511335
11336- EXP cmpop;
11336+
11337+ EXP cmpop = exp.op;
1133711338 if (auto e = exp.op_overload(sc, &cmpop))
1133811339 {
1133911340 if (! e.type.isscalar() && e.type.equals(exp.e1.type))
@@ -11343,13 +11344,46 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
1134311344 }
1134411345 if (e.op == EXP .call)
1134511346 {
11347+
11348+ if (t1.ty == Tclass && t2.ty == Tclass)
11349+ {
11350+ // Lower to object.__cmp(e1, e2)
11351+ Expression cl = new IdentifierExp(exp.loc, Id.empty);
11352+ cl = new DotIdExp(exp.loc, cl, Id.object);
11353+ cl = new DotIdExp(exp.loc, cl, Id.__cmp);
11354+ cl = cl.expressionSemantic(sc);
11355+
11356+ auto arguments = new Expressions();
11357+ // Check if op_overload found a better match by calling e2.opCmp(e1)
11358+ // If the operands were swapped, then the result must be reversed
11359+ // e1.opCmp(e2) == -e2.opCmp(e1)
11360+ // cmpop takes care of this
11361+ if (exp.op == cmpop)
11362+ {
11363+ arguments.push(exp.e1);
11364+ arguments.push(exp.e2);
11365+ }
11366+ else
11367+ {
11368+ // Use better match found by op_overload
11369+ arguments.push(exp.e2);
11370+ arguments.push(exp.e1);
11371+ }
11372+
11373+ cl = new CallExp(exp.loc, cl, arguments);
11374+ cl = new CmpExp(cmpop, exp.loc, cl, new IntegerExp(0 ));
11375+ result = cl.expressionSemantic(sc);
11376+ return ;
11377+ }
11378+
1134611379 e = new CmpExp(cmpop, exp.loc, e, IntegerExp.literal! 0 );
1134711380 e = e.expressionSemantic(sc);
1134811381 }
1134911382 result = e;
1135011383 return ;
1135111384 }
1135211385
11386+
1135311387 if (Expression ex = typeCombine(exp, sc))
1135411388 {
1135511389 result = ex;
0 commit comments