// Copyright (C) 2016-2019 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 // . // { dg-do run { target c++11 } } // libstdc++/56166 #ifndef _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_USE_CXX11_ABI 0 #endif #include #include static int fail_after = -1; template struct Allocator { using value_type = T; // Need these typedefs because COW string doesn't use allocator_traits. using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using difference_type = long; using size_type = unsigned long; template struct rebind { using other = Allocator; }; Allocator() { } template Allocator(const Allocator&) { } T* allocate(size_type n) { if (fail_after >= 0) { if (fail_after-- == 0) { throw std::bad_alloc(); } } return (T*)new char[n * sizeof(T)]; } void deallocate(T* p, size_type) { delete[] (char*)p; } }; template bool operator==(const Allocator&, const Allocator&) { return true; } template bool operator!=(const Allocator&, const Allocator&) { return false; } using string = __gnu_cxx::__versa_string, Allocator, __gnu_cxx::__rc_string_base>; string f() { string s1("xxxxxx"); string s2 = s1; s1.clear(); return s2; } int main() { for (int i = 0; i < 10; i++) { try { fail_after = i; f(); break; } catch (std::bad_alloc) { } } }