+2018-01-29 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/83658
+ * include/std/any (any::__do_emplace): Only set _M_manager after
+ constructing the contained object.
+ * testsuite/20_util/any/misc/any_cast_neg.cc: Adjust dg-error line.
+ * testsuite/20_util/any/modifiers/83658.cc: New test.
+
2018-01-25 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/81076
/**
* @brief A type-safe container of any type.
- *
+ *
* An @c any object's state is either empty or it stores a contained object
* of CopyConstructible type.
*/
void __do_emplace(_Args&&... __args)
{
reset();
- _M_manager = &_Mgr::_S_manage;
_Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
+ _M_manager = &_Mgr::_S_manage;
}
/// Emplace with an object created from @p __il and @p __args as
void __do_emplace(initializer_list<_Up> __il, _Args&&... __args)
{
reset();
- _M_manager = &_Mgr::_S_manage;
_Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
+ _M_manager = &_Mgr::_S_manage;
}
public:
_Decay<_ValueType>, _Args&&...>::type
emplace(_Args&&... __args)
{
- __do_emplace<_Decay<_ValueType>>
- (std::forward<_Args>(__args)...);
+ __do_emplace<_Decay<_ValueType>>(std::forward<_Args>(__args)...);
any::_Arg __arg;
this->_M_manager(any::_Op_access, this, &__arg);
return *static_cast<_Decay<_ValueType>*>(__arg._M_obj);
_Args&&...>::type
emplace(initializer_list<_Up> __il, _Args&&... __args)
{
- __do_emplace<_Decay<_ValueType>, _Up>
- (__il, std::forward<_Args>(__args)...);
+ __do_emplace<_Decay<_ValueType>, _Up>(__il,
+ std::forward<_Args>(__args)...);
any::_Arg __arg;
this->_M_manager(any::_Op_access, this, &__arg);
return *static_cast<_Decay<_ValueType>*>(__arg._M_obj);
}
/// @}
-
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
--- /dev/null
+// Copyright (C) 2018 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// 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 <any>
+#include <new>
+#include <testsuite_hooks.h>
+
+struct E : std::bad_alloc { };
+
+struct X
+{
+ X() = default;
+ X(std::initializer_list<int>) { }
+
+ // Prevents small-object optimization:
+ X(const X&) noexcept(false) { }
+
+ static void* operator new(std::size_t) { throw E{}; }
+ static void operator delete(void*, std::size_t) noexcept { }
+};
+
+void
+test01()
+{
+ std::any a;
+ try
+ {
+ a.emplace<X>();
+ VERIFY(false);
+ }
+ catch (const E&)
+ {
+ VERIFY( !a.has_value() );
+ }
+}
+
+void
+test02()
+{
+ std::any a;
+ try
+ {
+ a.emplace<X>(std::initializer_list<int>{});
+ VERIFY(false);
+ }
+ catch (const E&)
+ {
+ VERIFY( !a.has_value() );
+ }
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}