From cb885a6f05aa4f93518c9ab7ee161c0a1b9f39d8 Mon Sep 17 00:00:00 2001 From: Oleg Finkelshteyn Date: Tue, 21 Dec 2021 10:02:29 +0100 Subject: [PATCH] Fix relational::compare_same_type. A hash collision was needed to elicit this bug because basic::compare returns early without calling compare_same_type if hashes differ. Reported by Feng Feng . --- check/exam_relational.cpp | 16 ++++++++++++++++ ginac/relational.cpp | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/check/exam_relational.cpp b/check/exam_relational.cpp index 3b652b05..aeff144b 100644 --- a/check/exam_relational.cpp +++ b/check/exam_relational.cpp @@ -116,6 +116,21 @@ static unsigned exam_relational_arith() return result; } +// Comparisons should maintain ordering invariants +static unsigned exam_relational_order() +{ + unsigned result = 0; + numeric i = 1ll<<32, j = i+1; + symbol a; + relational x = i==a, y = j==a; + if (x.compare(y) != -y.compare(x)) { + clog << "comparison should be antisymmetric." << endl; + result += 1; + } + + return result; +} + unsigned exam_relational() { unsigned result = 0; @@ -125,6 +140,7 @@ unsigned exam_relational() result += exam_relational_elementary(); cout << '.' << flush; result += exam_relational_possymbol(); cout << '.' << flush; result += exam_relational_arith(); cout << '.' << flush; + result += exam_relational_order(); cout << '.' << flush; return result; } diff --git a/ginac/relational.cpp b/ginac/relational.cpp index 599a2635..dbc541a3 100644 --- a/ginac/relational.cpp +++ b/ginac/relational.cpp @@ -223,8 +223,8 @@ int relational::compare_same_type(const basic & other) const return (o < oth.o) ? -1 : 1; break; } - const int lcmpval = lh.compare(oth.rh); - return (lcmpval!=0) ? lcmpval : rh.compare(oth.lh); + const int lcmpval = lh.compare(oth.lh); + return (lcmpval!=0) ? lcmpval : rh.compare(oth.rh); } bool relational::match_same_type(const basic & other) const -- 2.44.0