1*4684ddb6SLionel Sambuc //===------------------------ stdexcept.cpp -------------------------------===// 2*4684ddb6SLionel Sambuc // 3*4684ddb6SLionel Sambuc // The LLVM Compiler Infrastructure 4*4684ddb6SLionel Sambuc // 5*4684ddb6SLionel Sambuc // This file is dual licensed under the MIT and the University of Illinois Open 6*4684ddb6SLionel Sambuc // Source Licenses. See LICENSE.TXT for details. 7*4684ddb6SLionel Sambuc // 8*4684ddb6SLionel Sambuc //===----------------------------------------------------------------------===// 9*4684ddb6SLionel Sambuc 10*4684ddb6SLionel Sambuc #include "stdexcept" 11*4684ddb6SLionel Sambuc #include "new" 12*4684ddb6SLionel Sambuc #include "string" 13*4684ddb6SLionel Sambuc #include <cstdlib> 14*4684ddb6SLionel Sambuc #include <cstring> 15*4684ddb6SLionel Sambuc #include <cstdint> 16*4684ddb6SLionel Sambuc #include <cstddef> 17*4684ddb6SLionel Sambuc #include "system_error" 18*4684ddb6SLionel Sambuc 19*4684ddb6SLionel Sambuc #ifndef __has_include 20*4684ddb6SLionel Sambuc #define __has_include(inc) 0 21*4684ddb6SLionel Sambuc #endif 22*4684ddb6SLionel Sambuc 23*4684ddb6SLionel Sambuc #ifdef __APPLE__ 24*4684ddb6SLionel Sambuc #include <cxxabi.h> 25*4684ddb6SLionel Sambuc #elif defined(LIBCXXRT) || __has_include(<cxxabi.h>) 26*4684ddb6SLionel Sambuc #include <cxxabi.h> 27*4684ddb6SLionel Sambuc #endif 28*4684ddb6SLionel Sambuc 29*4684ddb6SLionel Sambuc // Note: optimize for size 30*4684ddb6SLionel Sambuc 31*4684ddb6SLionel Sambuc #if ! defined(_LIBCPP_MSVC) 32*4684ddb6SLionel Sambuc #pragma GCC visibility push(hidden) 33*4684ddb6SLionel Sambuc #endif 34*4684ddb6SLionel Sambuc 35*4684ddb6SLionel Sambuc namespace 36*4684ddb6SLionel Sambuc { 37*4684ddb6SLionel Sambuc 38*4684ddb6SLionel Sambuc class __libcpp_nmstr 39*4684ddb6SLionel Sambuc { 40*4684ddb6SLionel Sambuc private: 41*4684ddb6SLionel Sambuc const char* str_; 42*4684ddb6SLionel Sambuc 43*4684ddb6SLionel Sambuc typedef std::size_t unused_t; 44*4684ddb6SLionel Sambuc typedef std::ptrdiff_t count_t; 45*4684ddb6SLionel Sambuc 46*4684ddb6SLionel Sambuc static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) + 47*4684ddb6SLionel Sambuc sizeof(count_t)); 48*4684ddb6SLionel Sambuc 49*4684ddb6SLionel Sambuc count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));} 50*4684ddb6SLionel Sambuc public: 51*4684ddb6SLionel Sambuc explicit __libcpp_nmstr(const char* msg); 52*4684ddb6SLionel Sambuc __libcpp_nmstr(const __libcpp_nmstr& s) _NOEXCEPT; 53*4684ddb6SLionel Sambuc __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _NOEXCEPT; 54*4684ddb6SLionel Sambuc ~__libcpp_nmstr(); 55*4684ddb6SLionel Sambuc const char* c_str() const _NOEXCEPT {return str_;} 56*4684ddb6SLionel Sambuc }; 57*4684ddb6SLionel Sambuc 58*4684ddb6SLionel Sambuc __libcpp_nmstr::__libcpp_nmstr(const char* msg) 59*4684ddb6SLionel Sambuc { 60*4684ddb6SLionel Sambuc std::size_t len = strlen(msg); 61*4684ddb6SLionel Sambuc str_ = new char[len + 1 + offset]; 62*4684ddb6SLionel Sambuc unused_t* c = (unused_t*)str_; 63*4684ddb6SLionel Sambuc c[0] = c[1] = len; 64*4684ddb6SLionel Sambuc str_ += offset; 65*4684ddb6SLionel Sambuc count() = 0; 66*4684ddb6SLionel Sambuc std::memcpy(const_cast<char*>(c_str()), msg, len + 1); 67*4684ddb6SLionel Sambuc } 68*4684ddb6SLionel Sambuc 69*4684ddb6SLionel Sambuc inline 70*4684ddb6SLionel Sambuc __libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) _NOEXCEPT 71*4684ddb6SLionel Sambuc : str_(s.str_) 72*4684ddb6SLionel Sambuc { 73*4684ddb6SLionel Sambuc __sync_add_and_fetch(&count(), 1); 74*4684ddb6SLionel Sambuc } 75*4684ddb6SLionel Sambuc 76*4684ddb6SLionel Sambuc __libcpp_nmstr& 77*4684ddb6SLionel Sambuc __libcpp_nmstr::operator=(const __libcpp_nmstr& s) _NOEXCEPT 78*4684ddb6SLionel Sambuc { 79*4684ddb6SLionel Sambuc const char* p = str_; 80*4684ddb6SLionel Sambuc str_ = s.str_; 81*4684ddb6SLionel Sambuc __sync_add_and_fetch(&count(), 1); 82*4684ddb6SLionel Sambuc if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), count_t(-1)) < 0) 83*4684ddb6SLionel Sambuc delete [] (p-offset); 84*4684ddb6SLionel Sambuc return *this; 85*4684ddb6SLionel Sambuc } 86*4684ddb6SLionel Sambuc 87*4684ddb6SLionel Sambuc inline 88*4684ddb6SLionel Sambuc __libcpp_nmstr::~__libcpp_nmstr() 89*4684ddb6SLionel Sambuc { 90*4684ddb6SLionel Sambuc if (__sync_add_and_fetch(&count(), count_t(-1)) < 0) 91*4684ddb6SLionel Sambuc delete [] (str_ - offset); 92*4684ddb6SLionel Sambuc } 93*4684ddb6SLionel Sambuc 94*4684ddb6SLionel Sambuc } 95*4684ddb6SLionel Sambuc 96*4684ddb6SLionel Sambuc #if ! defined(_LIBCPP_MSVC) 97*4684ddb6SLionel Sambuc #pragma GCC visibility pop 98*4684ddb6SLionel Sambuc #endif 99*4684ddb6SLionel Sambuc 100*4684ddb6SLionel Sambuc namespace std // purposefully not using versioning namespace 101*4684ddb6SLionel Sambuc { 102*4684ddb6SLionel Sambuc 103*4684ddb6SLionel Sambuc logic_error::logic_error(const string& msg) 104*4684ddb6SLionel Sambuc { 105*4684ddb6SLionel Sambuc __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 106*4684ddb6SLionel Sambuc ::new(&s) __libcpp_nmstr(msg.c_str()); 107*4684ddb6SLionel Sambuc } 108*4684ddb6SLionel Sambuc 109*4684ddb6SLionel Sambuc logic_error::logic_error(const char* msg) 110*4684ddb6SLionel Sambuc { 111*4684ddb6SLionel Sambuc __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 112*4684ddb6SLionel Sambuc ::new(&s) __libcpp_nmstr(msg); 113*4684ddb6SLionel Sambuc } 114*4684ddb6SLionel Sambuc 115*4684ddb6SLionel Sambuc logic_error::logic_error(const logic_error& le) _NOEXCEPT 116*4684ddb6SLionel Sambuc { 117*4684ddb6SLionel Sambuc __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 118*4684ddb6SLionel Sambuc ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 119*4684ddb6SLionel Sambuc } 120*4684ddb6SLionel Sambuc 121*4684ddb6SLionel Sambuc logic_error& 122*4684ddb6SLionel Sambuc logic_error::operator=(const logic_error& le) _NOEXCEPT 123*4684ddb6SLionel Sambuc { 124*4684ddb6SLionel Sambuc __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 125*4684ddb6SLionel Sambuc const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 126*4684ddb6SLionel Sambuc s1 = s2; 127*4684ddb6SLionel Sambuc return *this; 128*4684ddb6SLionel Sambuc } 129*4684ddb6SLionel Sambuc 130*4684ddb6SLionel Sambuc #if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX) 131*4684ddb6SLionel Sambuc 132*4684ddb6SLionel Sambuc logic_error::~logic_error() _NOEXCEPT 133*4684ddb6SLionel Sambuc { 134*4684ddb6SLionel Sambuc __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 135*4684ddb6SLionel Sambuc s.~__libcpp_nmstr(); 136*4684ddb6SLionel Sambuc } 137*4684ddb6SLionel Sambuc 138*4684ddb6SLionel Sambuc const char* 139*4684ddb6SLionel Sambuc logic_error::what() const _NOEXCEPT 140*4684ddb6SLionel Sambuc { 141*4684ddb6SLionel Sambuc __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 142*4684ddb6SLionel Sambuc return s.c_str(); 143*4684ddb6SLionel Sambuc } 144*4684ddb6SLionel Sambuc 145*4684ddb6SLionel Sambuc #endif 146*4684ddb6SLionel Sambuc 147*4684ddb6SLionel Sambuc runtime_error::runtime_error(const string& msg) 148*4684ddb6SLionel Sambuc { 149*4684ddb6SLionel Sambuc __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 150*4684ddb6SLionel Sambuc ::new(&s) __libcpp_nmstr(msg.c_str()); 151*4684ddb6SLionel Sambuc } 152*4684ddb6SLionel Sambuc 153*4684ddb6SLionel Sambuc runtime_error::runtime_error(const char* msg) 154*4684ddb6SLionel Sambuc { 155*4684ddb6SLionel Sambuc __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 156*4684ddb6SLionel Sambuc ::new(&s) __libcpp_nmstr(msg); 157*4684ddb6SLionel Sambuc } 158*4684ddb6SLionel Sambuc 159*4684ddb6SLionel Sambuc runtime_error::runtime_error(const runtime_error& le) _NOEXCEPT 160*4684ddb6SLionel Sambuc { 161*4684ddb6SLionel Sambuc __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 162*4684ddb6SLionel Sambuc ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 163*4684ddb6SLionel Sambuc } 164*4684ddb6SLionel Sambuc 165*4684ddb6SLionel Sambuc runtime_error& 166*4684ddb6SLionel Sambuc runtime_error::operator=(const runtime_error& le) _NOEXCEPT 167*4684ddb6SLionel Sambuc { 168*4684ddb6SLionel Sambuc __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 169*4684ddb6SLionel Sambuc const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 170*4684ddb6SLionel Sambuc s1 = s2; 171*4684ddb6SLionel Sambuc return *this; 172*4684ddb6SLionel Sambuc } 173*4684ddb6SLionel Sambuc 174*4684ddb6SLionel Sambuc #if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX) 175*4684ddb6SLionel Sambuc 176*4684ddb6SLionel Sambuc runtime_error::~runtime_error() _NOEXCEPT 177*4684ddb6SLionel Sambuc { 178*4684ddb6SLionel Sambuc __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 179*4684ddb6SLionel Sambuc s.~__libcpp_nmstr(); 180*4684ddb6SLionel Sambuc } 181*4684ddb6SLionel Sambuc 182*4684ddb6SLionel Sambuc const char* 183*4684ddb6SLionel Sambuc runtime_error::what() const _NOEXCEPT 184*4684ddb6SLionel Sambuc { 185*4684ddb6SLionel Sambuc __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 186*4684ddb6SLionel Sambuc return s.c_str(); 187*4684ddb6SLionel Sambuc } 188*4684ddb6SLionel Sambuc 189*4684ddb6SLionel Sambuc domain_error::~domain_error() _NOEXCEPT {} 190*4684ddb6SLionel Sambuc invalid_argument::~invalid_argument() _NOEXCEPT {} 191*4684ddb6SLionel Sambuc length_error::~length_error() _NOEXCEPT {} 192*4684ddb6SLionel Sambuc out_of_range::~out_of_range() _NOEXCEPT {} 193*4684ddb6SLionel Sambuc 194*4684ddb6SLionel Sambuc range_error::~range_error() _NOEXCEPT {} 195*4684ddb6SLionel Sambuc overflow_error::~overflow_error() _NOEXCEPT {} 196*4684ddb6SLionel Sambuc underflow_error::~underflow_error() _NOEXCEPT {} 197*4684ddb6SLionel Sambuc 198*4684ddb6SLionel Sambuc #endif 199*4684ddb6SLionel Sambuc 200*4684ddb6SLionel Sambuc } // std 201