13e519524SHoward Hinnant //===------------------------ stdexcept.cpp -------------------------------===// 23e519524SHoward Hinnant // 35b08a8a4SHoward Hinnant // The LLVM Compiler Infrastructure 43e519524SHoward Hinnant // 5412dbebeSHoward Hinnant // This file is dual licensed under the MIT and the University of Illinois Open 6412dbebeSHoward Hinnant // Source Licenses. See LICENSE.TXT for details. 73e519524SHoward Hinnant // 83e519524SHoward Hinnant //===----------------------------------------------------------------------===// 93e519524SHoward Hinnant 103e519524SHoward Hinnant #include "stdexcept" 113e519524SHoward Hinnant #include "new" 123e519524SHoward Hinnant #include "string" 133e519524SHoward Hinnant #include <cstdlib> 143e519524SHoward Hinnant #include <cstring> 153e519524SHoward Hinnant #include <cstdint> 163e519524SHoward Hinnant #include <cstddef> 173e519524SHoward Hinnant #include "system_error" 18*11ffde3dSRichard Smith 19*11ffde3dSRichard Smith // Use <cxxabi.h> to determine whether we're linking against libc++abi. 20*11ffde3dSRichard Smith #if __has_include(<cxxabi.h>) 21f95d9f0aSHoward Hinnant #include <cxxabi.h> 22*11ffde3dSRichard Smith #endif 233e519524SHoward Hinnant 243e519524SHoward Hinnant // Note: optimize for size 253e519524SHoward Hinnant 263e519524SHoward Hinnant #pragma GCC visibility push(hidden) 273e519524SHoward Hinnant 283e519524SHoward Hinnant namespace 293e519524SHoward Hinnant { 303e519524SHoward Hinnant 313e519524SHoward Hinnant class __libcpp_nmstr 323e519524SHoward Hinnant { 333e519524SHoward Hinnant private: 343e519524SHoward Hinnant const char* str_; 353e519524SHoward Hinnant 363e519524SHoward Hinnant typedef std::size_t unused_t; 373e519524SHoward Hinnant typedef std::int32_t count_t; 383e519524SHoward Hinnant 393e519524SHoward Hinnant static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) + 403e519524SHoward Hinnant sizeof(count_t)); 413e519524SHoward Hinnant 42a62f2899SHoward Hinnant count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));} 433e519524SHoward Hinnant public: 443e519524SHoward Hinnant explicit __libcpp_nmstr(const char* msg); 453e519524SHoward Hinnant __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 463e519524SHoward Hinnant __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 473e519524SHoward Hinnant ~__libcpp_nmstr() _LIBCPP_CANTTHROW; 48a62f2899SHoward Hinnant const char* c_str() const _NOEXCEPT {return str_;} 493e519524SHoward Hinnant }; 503e519524SHoward Hinnant 513e519524SHoward Hinnant __libcpp_nmstr::__libcpp_nmstr(const char* msg) 523e519524SHoward Hinnant { 533e519524SHoward Hinnant std::size_t len = strlen(msg); 543e519524SHoward Hinnant str_ = new char[len + 1 + offset]; 553e519524SHoward Hinnant unused_t* c = (unused_t*)str_; 563e519524SHoward Hinnant c[0] = c[1] = len; 573e519524SHoward Hinnant str_ += offset; 583e519524SHoward Hinnant count() = 0; 593e519524SHoward Hinnant std::strcpy(const_cast<char*>(c_str()), msg); 603e519524SHoward Hinnant } 613e519524SHoward Hinnant 623e519524SHoward Hinnant inline 633e519524SHoward Hinnant __libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) 643e519524SHoward Hinnant : str_(s.str_) 653e519524SHoward Hinnant { 66128ba719SHoward Hinnant __sync_add_and_fetch(&count(), 1); 673e519524SHoward Hinnant } 683e519524SHoward Hinnant 693e519524SHoward Hinnant __libcpp_nmstr& 703e519524SHoward Hinnant __libcpp_nmstr::operator=(const __libcpp_nmstr& s) 713e519524SHoward Hinnant { 723e519524SHoward Hinnant const char* p = str_; 733e519524SHoward Hinnant str_ = s.str_; 74128ba719SHoward Hinnant __sync_add_and_fetch(&count(), 1); 75128ba719SHoward Hinnant if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), -1) < 0) 763e519524SHoward Hinnant delete [] (p-offset); 773e519524SHoward Hinnant return *this; 783e519524SHoward Hinnant } 793e519524SHoward Hinnant 803e519524SHoward Hinnant inline 813e519524SHoward Hinnant __libcpp_nmstr::~__libcpp_nmstr() 823e519524SHoward Hinnant { 83128ba719SHoward Hinnant if (__sync_add_and_fetch(&count(), -1) < 0) 843e519524SHoward Hinnant delete [] (str_ - offset); 853e519524SHoward Hinnant } 863e519524SHoward Hinnant 873e519524SHoward Hinnant } 883e519524SHoward Hinnant 890a779b97SDaniel Dunbar #pragma GCC visibility pop 903e519524SHoward Hinnant 913e519524SHoward Hinnant namespace std // purposefully not using versioning namespace 923e519524SHoward Hinnant { 933e519524SHoward Hinnant 943e519524SHoward Hinnant logic_error::logic_error(const string& msg) 953e519524SHoward Hinnant { 963e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 973e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg.c_str()); 983e519524SHoward Hinnant } 993e519524SHoward Hinnant 1003e519524SHoward Hinnant logic_error::logic_error(const char* msg) 1013e519524SHoward Hinnant { 1023e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1033e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg); 1043e519524SHoward Hinnant } 1053e519524SHoward Hinnant 106a62f2899SHoward Hinnant logic_error::logic_error(const logic_error& le) _NOEXCEPT 1073e519524SHoward Hinnant { 1083e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1093e519524SHoward Hinnant ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 1103e519524SHoward Hinnant } 1113e519524SHoward Hinnant 1123e519524SHoward Hinnant logic_error& 113a62f2899SHoward Hinnant logic_error::operator=(const logic_error& le) _NOEXCEPT 1143e519524SHoward Hinnant { 1153e519524SHoward Hinnant __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 1163e519524SHoward Hinnant const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 1173e519524SHoward Hinnant s1 = s2; 1183e519524SHoward Hinnant return *this; 1193e519524SHoward Hinnant } 1203e519524SHoward Hinnant 121f95d9f0aSHoward Hinnant #ifndef _LIBCPPABI_VERSION 122f95d9f0aSHoward Hinnant 123a62f2899SHoward Hinnant logic_error::~logic_error() _NOEXCEPT 1243e519524SHoward Hinnant { 1253e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1263e519524SHoward Hinnant s.~__libcpp_nmstr(); 1273e519524SHoward Hinnant } 1283e519524SHoward Hinnant 1293e519524SHoward Hinnant const char* 130a62f2899SHoward Hinnant logic_error::what() const _NOEXCEPT 1313e519524SHoward Hinnant { 1323e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1333e519524SHoward Hinnant return s.c_str(); 1343e519524SHoward Hinnant } 1353e519524SHoward Hinnant 136f95d9f0aSHoward Hinnant #endif 137f95d9f0aSHoward Hinnant 1383e519524SHoward Hinnant runtime_error::runtime_error(const string& msg) 1393e519524SHoward Hinnant { 1403e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1413e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg.c_str()); 1423e519524SHoward Hinnant } 1433e519524SHoward Hinnant 1443e519524SHoward Hinnant runtime_error::runtime_error(const char* msg) 1453e519524SHoward Hinnant { 1463e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1473e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg); 1483e519524SHoward Hinnant } 1493e519524SHoward Hinnant 150a62f2899SHoward Hinnant runtime_error::runtime_error(const runtime_error& le) _NOEXCEPT 1513e519524SHoward Hinnant { 1523e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1533e519524SHoward Hinnant ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 1543e519524SHoward Hinnant } 1553e519524SHoward Hinnant 1563e519524SHoward Hinnant runtime_error& 157a62f2899SHoward Hinnant runtime_error::operator=(const runtime_error& le) _NOEXCEPT 1583e519524SHoward Hinnant { 1593e519524SHoward Hinnant __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 1603e519524SHoward Hinnant const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 1613e519524SHoward Hinnant s1 = s2; 1623e519524SHoward Hinnant return *this; 1633e519524SHoward Hinnant } 1643e519524SHoward Hinnant 165f95d9f0aSHoward Hinnant #ifndef _LIBCPPABI_VERSION 166f95d9f0aSHoward Hinnant 167a62f2899SHoward Hinnant runtime_error::~runtime_error() _NOEXCEPT 1683e519524SHoward Hinnant { 1693e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1703e519524SHoward Hinnant s.~__libcpp_nmstr(); 1713e519524SHoward Hinnant } 1723e519524SHoward Hinnant 1733e519524SHoward Hinnant const char* 174a62f2899SHoward Hinnant runtime_error::what() const _NOEXCEPT 1753e519524SHoward Hinnant { 1763e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1773e519524SHoward Hinnant return s.c_str(); 1783e519524SHoward Hinnant } 1793e519524SHoward Hinnant 180a62f2899SHoward Hinnant domain_error::~domain_error() _NOEXCEPT {} 181a62f2899SHoward Hinnant invalid_argument::~invalid_argument() _NOEXCEPT {} 182a62f2899SHoward Hinnant length_error::~length_error() _NOEXCEPT {} 183a62f2899SHoward Hinnant out_of_range::~out_of_range() _NOEXCEPT {} 1843e519524SHoward Hinnant 185a62f2899SHoward Hinnant range_error::~range_error() _NOEXCEPT {} 186a62f2899SHoward Hinnant overflow_error::~overflow_error() _NOEXCEPT {} 187a62f2899SHoward Hinnant underflow_error::~underflow_error() _NOEXCEPT {} 1883e519524SHoward Hinnant 189f95d9f0aSHoward Hinnant #endif 190f95d9f0aSHoward Hinnant 1913e519524SHoward Hinnant } // std 192