diff --git a/flang/include/flang/Common/restorer.h b/flang/include/flang/Common/restorer.h --- a/flang/include/flang/Common/restorer.h +++ b/flang/include/flang/Common/restorer.h @@ -22,10 +22,34 @@ namespace Fortran::common { template class Restorer { public: - explicit Restorer(A &p) : p_{p}, original_{std::move(p)} {} - ~Restorer() { p_ = std::move(original_); } + explicit Restorer(A &p) : active_{true}, p_{p}, original_{std::move(p)} {} + ~Restorer() { Release(); } + + Restorer(const Restorer &) = delete; + Restorer(Restorer &&that) + : active_{that.active_}, p_{that.p_}, original_{ + std::move(that.original_)} { + that.active_ = false; + } + + const Restorer &operator=(const Restorer &) = delete; + const Restorer &operator=(Restorer &&that) { + Release(); + if (that.active_) { + p_ = that.p_; + original_ = std::move(that.original_); + that.active = false; + } + } private: + void Release() { + if (active_) + p_ = std::move(original_); + active_ = false; + } + + bool active_; A &p_; A original_; };