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*f95d9f0aSHoward Hinnant #include <cxxabi.h> 193e519524SHoward Hinnant 203e519524SHoward Hinnant // Note: optimize for size 213e519524SHoward Hinnant 223e519524SHoward Hinnant #pragma GCC visibility push(hidden) 233e519524SHoward Hinnant 243e519524SHoward Hinnant namespace 253e519524SHoward Hinnant { 263e519524SHoward Hinnant 273e519524SHoward Hinnant class __libcpp_nmstr 283e519524SHoward Hinnant { 293e519524SHoward Hinnant private: 303e519524SHoward Hinnant const char* str_; 313e519524SHoward Hinnant 323e519524SHoward Hinnant typedef std::size_t unused_t; 333e519524SHoward Hinnant typedef std::int32_t count_t; 343e519524SHoward Hinnant 353e519524SHoward Hinnant static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) + 363e519524SHoward Hinnant sizeof(count_t)); 373e519524SHoward Hinnant 38a62f2899SHoward Hinnant count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));} 393e519524SHoward Hinnant public: 403e519524SHoward Hinnant explicit __libcpp_nmstr(const char* msg); 413e519524SHoward Hinnant __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 423e519524SHoward Hinnant __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 433e519524SHoward Hinnant ~__libcpp_nmstr() _LIBCPP_CANTTHROW; 44a62f2899SHoward Hinnant const char* c_str() const _NOEXCEPT {return str_;} 453e519524SHoward Hinnant }; 463e519524SHoward Hinnant 473e519524SHoward Hinnant __libcpp_nmstr::__libcpp_nmstr(const char* msg) 483e519524SHoward Hinnant { 493e519524SHoward Hinnant std::size_t len = strlen(msg); 503e519524SHoward Hinnant str_ = new char[len + 1 + offset]; 513e519524SHoward Hinnant unused_t* c = (unused_t*)str_; 523e519524SHoward Hinnant c[0] = c[1] = len; 533e519524SHoward Hinnant str_ += offset; 543e519524SHoward Hinnant count() = 0; 553e519524SHoward Hinnant std::strcpy(const_cast<char*>(c_str()), msg); 563e519524SHoward Hinnant } 573e519524SHoward Hinnant 583e519524SHoward Hinnant inline 593e519524SHoward Hinnant __libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) 603e519524SHoward Hinnant : str_(s.str_) 613e519524SHoward Hinnant { 62128ba719SHoward Hinnant __sync_add_and_fetch(&count(), 1); 633e519524SHoward Hinnant } 643e519524SHoward Hinnant 653e519524SHoward Hinnant __libcpp_nmstr& 663e519524SHoward Hinnant __libcpp_nmstr::operator=(const __libcpp_nmstr& s) 673e519524SHoward Hinnant { 683e519524SHoward Hinnant const char* p = str_; 693e519524SHoward Hinnant str_ = s.str_; 70128ba719SHoward Hinnant __sync_add_and_fetch(&count(), 1); 71128ba719SHoward Hinnant if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), -1) < 0) 723e519524SHoward Hinnant delete [] (p-offset); 733e519524SHoward Hinnant return *this; 743e519524SHoward Hinnant } 753e519524SHoward Hinnant 763e519524SHoward Hinnant inline 773e519524SHoward Hinnant __libcpp_nmstr::~__libcpp_nmstr() 783e519524SHoward Hinnant { 79128ba719SHoward Hinnant if (__sync_add_and_fetch(&count(), -1) < 0) 803e519524SHoward Hinnant delete [] (str_ - offset); 813e519524SHoward Hinnant } 823e519524SHoward Hinnant 833e519524SHoward Hinnant } 843e519524SHoward Hinnant 850a779b97SDaniel Dunbar #pragma GCC visibility pop 863e519524SHoward Hinnant 873e519524SHoward Hinnant namespace std // purposefully not using versioning namespace 883e519524SHoward Hinnant { 893e519524SHoward Hinnant 903e519524SHoward Hinnant logic_error::logic_error(const string& msg) 913e519524SHoward Hinnant { 923e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 933e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg.c_str()); 943e519524SHoward Hinnant } 953e519524SHoward Hinnant 963e519524SHoward Hinnant logic_error::logic_error(const char* msg) 973e519524SHoward Hinnant { 983e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 993e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg); 1003e519524SHoward Hinnant } 1013e519524SHoward Hinnant 102a62f2899SHoward Hinnant logic_error::logic_error(const logic_error& le) _NOEXCEPT 1033e519524SHoward Hinnant { 1043e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1053e519524SHoward Hinnant ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 1063e519524SHoward Hinnant } 1073e519524SHoward Hinnant 1083e519524SHoward Hinnant logic_error& 109a62f2899SHoward Hinnant logic_error::operator=(const logic_error& le) _NOEXCEPT 1103e519524SHoward Hinnant { 1113e519524SHoward Hinnant __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 1123e519524SHoward Hinnant const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 1133e519524SHoward Hinnant s1 = s2; 1143e519524SHoward Hinnant return *this; 1153e519524SHoward Hinnant } 1163e519524SHoward Hinnant 117*f95d9f0aSHoward Hinnant #ifndef _LIBCPPABI_VERSION 118*f95d9f0aSHoward Hinnant 119a62f2899SHoward Hinnant logic_error::~logic_error() _NOEXCEPT 1203e519524SHoward Hinnant { 1213e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1223e519524SHoward Hinnant s.~__libcpp_nmstr(); 1233e519524SHoward Hinnant } 1243e519524SHoward Hinnant 1253e519524SHoward Hinnant const char* 126a62f2899SHoward Hinnant logic_error::what() const _NOEXCEPT 1273e519524SHoward Hinnant { 1283e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1293e519524SHoward Hinnant return s.c_str(); 1303e519524SHoward Hinnant } 1313e519524SHoward Hinnant 132*f95d9f0aSHoward Hinnant #endif 133*f95d9f0aSHoward Hinnant 1343e519524SHoward Hinnant runtime_error::runtime_error(const string& msg) 1353e519524SHoward Hinnant { 1363e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1373e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg.c_str()); 1383e519524SHoward Hinnant } 1393e519524SHoward Hinnant 1403e519524SHoward Hinnant runtime_error::runtime_error(const char* msg) 1413e519524SHoward Hinnant { 1423e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1433e519524SHoward Hinnant ::new(&s) __libcpp_nmstr(msg); 1443e519524SHoward Hinnant } 1453e519524SHoward Hinnant 146a62f2899SHoward Hinnant runtime_error::runtime_error(const runtime_error& le) _NOEXCEPT 1473e519524SHoward Hinnant { 1483e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1493e519524SHoward Hinnant ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 1503e519524SHoward Hinnant } 1513e519524SHoward Hinnant 1523e519524SHoward Hinnant runtime_error& 153a62f2899SHoward Hinnant runtime_error::operator=(const runtime_error& le) _NOEXCEPT 1543e519524SHoward Hinnant { 1553e519524SHoward Hinnant __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 1563e519524SHoward Hinnant const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 1573e519524SHoward Hinnant s1 = s2; 1583e519524SHoward Hinnant return *this; 1593e519524SHoward Hinnant } 1603e519524SHoward Hinnant 161*f95d9f0aSHoward Hinnant #ifndef _LIBCPPABI_VERSION 162*f95d9f0aSHoward Hinnant 163a62f2899SHoward Hinnant runtime_error::~runtime_error() _NOEXCEPT 1643e519524SHoward Hinnant { 1653e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1663e519524SHoward Hinnant s.~__libcpp_nmstr(); 1673e519524SHoward Hinnant } 1683e519524SHoward Hinnant 1693e519524SHoward Hinnant const char* 170a62f2899SHoward Hinnant runtime_error::what() const _NOEXCEPT 1713e519524SHoward Hinnant { 1723e519524SHoward Hinnant __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 1733e519524SHoward Hinnant return s.c_str(); 1743e519524SHoward Hinnant } 1753e519524SHoward Hinnant 176a62f2899SHoward Hinnant domain_error::~domain_error() _NOEXCEPT {} 177a62f2899SHoward Hinnant invalid_argument::~invalid_argument() _NOEXCEPT {} 178a62f2899SHoward Hinnant length_error::~length_error() _NOEXCEPT {} 179a62f2899SHoward Hinnant out_of_range::~out_of_range() _NOEXCEPT {} 1803e519524SHoward Hinnant 181a62f2899SHoward Hinnant range_error::~range_error() _NOEXCEPT {} 182a62f2899SHoward Hinnant overflow_error::~overflow_error() _NOEXCEPT {} 183a62f2899SHoward Hinnant underflow_error::~underflow_error() _NOEXCEPT {} 1843e519524SHoward Hinnant 185*f95d9f0aSHoward Hinnant #endif 186*f95d9f0aSHoward Hinnant 1873e519524SHoward Hinnant } // std 188