From 7805dc0c2358b7774ad08cd443cd945cbd940749 Mon Sep 17 00:00:00 2001 From: Richard Kreckel Date: Mon, 5 Apr 2021 20:46:55 +0200 Subject: [PATCH] [PATCH] Make ex::operator[] const dispatch to basic::operator[] const. It turned out that ex::operator[] const dispatched to non-const basic::operator[] because * member variable ex::bp is non-const and * ptr::operator*() returns a non-const T &. As a result, indexing failed for multiply referenced objects. Thanks to Vitaly Magerya for reporting this. --- check/exam_paranoia.cpp | 22 ++++++++++++++++++++++ ginac/ex.h | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/check/exam_paranoia.cpp b/check/exam_paranoia.cpp index 7a89f9de..af36238b 100644 --- a/check/exam_paranoia.cpp +++ b/check/exam_paranoia.cpp @@ -638,6 +638,27 @@ unsigned exam_paranoia26() return result; } +// Bug in collect() +// cf. https://www.ginac.de/pipermail/ginac-list/2021-March/002337.html +static unsigned exam_collect_multiply_referenced_lst() +{ + unsigned result = 0; + symbol x("x"), y("y"); + ex a = x + y; + ex l = lst{x, y}; + ex l2 = l; // make l a multiply referenced object + + try { + ex b = collect(a, l); + } catch (const std::runtime_error & e) { + clog << "collect(" << ", " << l << ") threw a runtime_error(" + << e.what() << ")" << endl; + ++result; + } + + return result; +} + unsigned exam_paranoia() { unsigned result = 0; @@ -672,6 +693,7 @@ unsigned exam_paranoia() result += exam_paranoia24(); cout << '.' << flush; result += exam_paranoia25(); cout << '.' << flush; result += exam_paranoia26(); cout << '.' << flush; + result += exam_collect_multiply_referenced_lst(); cout << '.' << flush; return result; } diff --git a/ginac/ex.h b/ginac/ex.h index dccf37af..6c9d429c 100644 --- a/ginac/ex.h +++ b/ginac/ex.h @@ -134,8 +134,8 @@ public: // operand access size_t nops() const { return bp->nops(); } ex op(size_t i) const { return bp->op(i); } - ex operator[](const ex & index) const { return (*bp)[index]; } - ex operator[](size_t i) const { return (*bp)[i]; } + ex operator[](const ex & index) const { return (const_cast(*bp))[index]; } + ex operator[](size_t i) const { return (const_cast(*bp))[i]; } ex & let_op(size_t i); ex & operator[](const ex & index); ex & operator[](size_t i); -- 2.44.0