]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/testsuite/20_util/variant/exception_safety.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / variant / exception_safety.cc
index 7e1b0f3bed1bbf58145792652ad9b341175ee376..3c9d591c50b1647f7ce50b87cd67708fa0c4e239 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Free Software Foundation, Inc.
+// Copyright (C) 2019-2022 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -15,7 +15,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 
 #include <variant>
@@ -25,6 +24,7 @@
 #include <memory>
 #include <functional>
 #include <any>
+#include <optional>
 #include <testsuite_hooks.h>
 
 void
@@ -169,10 +169,51 @@ test03()
   VERIFY( bad_emplace<std::unique_ptr<int>>(v) );
 }
 
+void
+test04()
+{
+  // LWG 2904. Make variant move-assignment more exception safe
+
+  struct ThrowOnCopy
+  {
+    ThrowOnCopy() { }
+    ThrowOnCopy(const ThrowOnCopy&) { throw 1; }
+    ThrowOnCopy& operator=(const ThrowOnCopy&) { throw "shouldn't happen"; }
+    ThrowOnCopy(ThrowOnCopy&&) noexcept { }
+  };
+
+  std::variant<int, ThrowOnCopy> v1(std::in_place_type<ThrowOnCopy>), v2(2);
+  try
+  {
+    v2 = v1; // uses variant<Types...>::operator=(const variant&)
+    VERIFY( false );
+  }
+  catch (int)
+  {
+    VERIFY( !v2.valueless_by_exception() );
+    VERIFY( v2.index() == 0 );
+    VERIFY( std::get<0>(v2) == 2 );
+  }
+
+  try
+  {
+    ThrowOnCopy toc;
+    v2 = toc; // uses variant<Types...>::operator=(T&&)
+    VERIFY( false );
+  }
+  catch (int)
+  {
+    VERIFY( !v2.valueless_by_exception() );
+    VERIFY( v2.index() == 0 );
+    VERIFY( std::get<0>(v2) == 2 );
+  }
+}
+
 int
 main()
 {
   test01();
   test02();
   test03();
+  test04();
 }