[PATCH] D88797: [flang] Fix copy elision assumption.

Michael Kruse via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 6 20:37:30 PST 2020


Meinersbur updated this revision to Diff 303612.
Meinersbur added a comment.

Implement @klausler's suggestion.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88797/new/

https://reviews.llvm.org/D88797

Files:
  flang/include/flang/Common/restorer.h
  flang/lib/Semantics/check-declarations.cpp


Index: flang/lib/Semantics/check-declarations.cpp
===================================================================
--- flang/lib/Semantics/check-declarations.cpp
+++ flang/lib/Semantics/check-declarations.cpp
@@ -1513,7 +1513,7 @@
 
 void CheckHelper::Check(const Scope &scope) {
   scope_ = &scope;
-  common::Restorer<const Symbol *> restorer{innermostSymbol_};
+  common::Restorer<const Symbol *> restorer{innermostSymbol_, innermostSymbol_};
   if (const Symbol * symbol{scope.symbol()}) {
     innermostSymbol_ = symbol;
   } else if (scope.IsDerivedType()) {
Index: flang/include/flang/Common/restorer.h
===================================================================
--- flang/include/flang/Common/restorer.h
+++ flang/include/flang/Common/restorer.h
@@ -22,9 +22,16 @@
 namespace Fortran::common {
 template <typename A> 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 <typename A, typename B>
 common::IfNoLvalue<Restorer<A>, B> ScopedSet(A &to, B &&from) {
-  Restorer<A> result{to};
+  A Original{std::move(to)};
   to = std::move(from);
-  return result;
+  return Restorer<A>{to, std::move(Original)};
 }
 template <typename A, typename B>
 common::IfNoLvalue<Restorer<A>, B> ScopedSet(A &to, const B &from) {
-  Restorer<A> result{to};
+  A Original{std::move(to)};
   to = from;
-  return result;
+  return Restorer<A>{to, std::move(Original)};
 }
 } // namespace Fortran::common
 #endif // FORTRAN_COMMON_RESTORER_H_


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D88797.303612.patch
Type: text/x-patch
Size: 1998 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201107/d3780e81/attachment.bin>


More information about the llvm-commits mailing list