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,9 +22,16 @@ namespace Fortran::common { template class Restorer { public: - explicit Restorer(A &p) : p_{p}, original_{std::move(p)} {} + explicit Restorer(A &p, A Original) : p_{p}, original_{std::move(Original)} {} ~Restorer() { p_ = std::move(original_); } + // Inhibit any recreation of this restorer that would result in two restorers + // trying to restore the same reference. + Restorer(const Restorer &) = delete; + Restorer(Restorer &&that) = delete; + const Restorer &operator=(const Restorer &) = delete; + const Restorer &operator=(Restorer &&that) = delete; + private: A &p_; A original_; @@ -32,15 +39,15 @@ template common::IfNoLvalue, B> ScopedSet(A &to, B &&from) { - Restorer result{to}; + A Original{std::move(to)}; to = std::move(from); - return result; + return Restorer{to, std::move(Original)}; } template common::IfNoLvalue, B> ScopedSet(A &to, const B &from) { - Restorer result{to}; + A Original{std::move(to)}; to = from; - return result; + return Restorer{to, std::move(Original)}; } } // namespace Fortran::common #endif // FORTRAN_COMMON_RESTORER_H_ diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -1513,7 +1513,7 @@ void CheckHelper::Check(const Scope &scope) { scope_ = &scope; - common::Restorer restorer{innermostSymbol_}; + common::Restorer restorer{innermostSymbol_, innermostSymbol_}; if (const Symbol * symbol{scope.symbol()}) { innermostSymbol_ = symbol; } else if (scope.IsDerivedType()) {