diff --git a/src/math/polynomial/algebraic_numbers.h b/src/math/polynomial/algebraic_numbers.h index 46cb3c6da..e60f8ea1a 100644 --- a/src/math/polynomial/algebraic_numbers.h +++ b/src/math/polynomial/algebraic_numbers.h @@ -381,7 +381,7 @@ namespace algebraic_numbers { - class anum { + class anum { enum anum_kind { BASIC = 0, ROOT }; void* m_cell; public: @@ -389,6 +389,17 @@ namespace algebraic_numbers { anum(basic_cell* cell) :m_cell(TAG(void*, cell, BASIC)) { } anum(algebraic_cell * cell):m_cell(TAG(void*, cell, ROOT)) { } + // Move nulls the source so std::sort's inner shifts stay alias-free + // if the comparator throws between moves (avoids a later double-free). + anum(anum const &) = default; + anum & operator=(anum const &) = default; + anum(anum && other) noexcept : m_cell(other.m_cell) { other.m_cell = nullptr; } + anum & operator=(anum && other) noexcept { + m_cell = other.m_cell; + other.m_cell = nullptr; + return *this; + } + bool is_basic() const { return GET_TAG(m_cell) == BASIC; } basic_cell * to_basic() const { SASSERT(is_basic()); return UNTAG(basic_cell*, m_cell); } algebraic_cell * to_algebraic() const { SASSERT(!is_basic()); return UNTAG(algebraic_cell*, m_cell); }