blob: ec7f666dc6d90f8c5c4f3a84aa99fd58c32bc05e [file] [log] [blame]
Howard Hinnant3e519522010-05-11 19:42:161//===------------------------ stdexcept.cpp -------------------------------===//
2//
Howard Hinnant5b08a8a2010-05-11 21:36:013// The LLVM Compiler Infrastructure
Howard Hinnant3e519522010-05-11 19:42:164//
Howard Hinnant412dbeb2010-11-16 22:09:025// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnant3e519522010-05-11 19:42:167//
8//===----------------------------------------------------------------------===//
9
10#include "stdexcept"
11#include "new"
12#include "string"
13#include <cstdlib>
14#include <cstring>
15#include <cstdint>
16#include <cstddef>
17#include "system_error"
Richard Smith11ffde32012-04-19 01:36:1218
Howard Hinnant49713b42012-09-03 18:13:1119#ifndef __has_include
20#define __has_include(inc) 0
21#endif
22
Marshall Clowb56e8582013-03-18 17:45:3423#ifdef __APPLE__
Howard Hinnant49713b42012-09-03 18:13:1124#include <cxxabi.h>
25#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)
Howard Hinnantf95d9f02012-02-17 19:24:4226#include <cxxabi.h>
Richard Smith11ffde32012-04-19 01:36:1227#endif
Howard Hinnant3e519522010-05-11 19:42:1628
29// Note: optimize for size
30
Howard Hinnant79710102013-10-04 22:12:5931#if ! defined(_LIBCPP_MSVC)
Howard Hinnant3e519522010-05-11 19:42:1632#pragma GCC visibility push(hidden)
Howard Hinnant79710102013-10-04 22:12:5933#endif
Howard Hinnant3e519522010-05-11 19:42:1634
35namespace
36{
37
38class __libcpp_nmstr
39{
40private:
41 const char* str_;
42
43 typedef std::size_t unused_t;
Howard Hinnantd79842c2012-08-08 16:17:3144 typedef std::ptrdiff_t count_t;
Howard Hinnant3e519522010-05-11 19:42:1645
46 static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) +
47 sizeof(count_t));
48
Joerg Sonnenberger634b9dd2014-01-04 17:43:0049 count_t& count() const _NOEXCEPT {return *const_cast<count_t *>(reinterpret_cast<const count_t *>(str_ - sizeof(count_t)));}
Howard Hinnant3e519522010-05-11 19:42:1650public:
51 explicit __libcpp_nmstr(const char* msg);
Howard Hinnant104024c2013-08-22 19:39:0352 __libcpp_nmstr(const __libcpp_nmstr& s) _NOEXCEPT;
53 __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _NOEXCEPT;
54 ~__libcpp_nmstr();
Howard Hinnanta62f2892011-05-26 19:48:0155 const char* c_str() const _NOEXCEPT {return str_;}
Howard Hinnant3e519522010-05-11 19:42:1656};
57
58__libcpp_nmstr::__libcpp_nmstr(const char* msg)
59{
60 std::size_t len = strlen(msg);
61 str_ = new char[len + 1 + offset];
Joerg Sonnenberger634b9dd2014-01-04 17:43:0062 unused_t* c = reinterpret_cast<unused_t*>(const_cast<char *>(str_));
Howard Hinnant3e519522010-05-11 19:42:1663 c[0] = c[1] = len;
64 str_ += offset;
65 count() = 0;
Howard Hinnant27841fd2013-06-29 23:53:2066 std::memcpy(const_cast<char*>(c_str()), msg, len + 1);
Howard Hinnant3e519522010-05-11 19:42:1667}
68
69inline
Howard Hinnant104024c2013-08-22 19:39:0370__libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1671 : str_(s.str_)
72{
Howard Hinnant128ba712010-05-24 17:49:4173 __sync_add_and_fetch(&count(), 1);
Howard Hinnant3e519522010-05-11 19:42:1674}
75
76__libcpp_nmstr&
Howard Hinnant104024c2013-08-22 19:39:0377__libcpp_nmstr::operator=(const __libcpp_nmstr& s) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:1678{
79 const char* p = str_;
80 str_ = s.str_;
Howard Hinnant128ba712010-05-24 17:49:4181 __sync_add_and_fetch(&count(), 1);
Alp Toker5fea9742014-01-17 16:17:2482 if (__sync_add_and_fetch(reinterpret_cast<count_t*>(const_cast<char*>(p)-sizeof(count_t)), count_t(-1)) < 0)
Howard Hinnant3e519522010-05-11 19:42:1683 delete [] (p-offset);
84 return *this;
85}
86
87inline
88__libcpp_nmstr::~__libcpp_nmstr()
89{
Howard Hinnantd79842c2012-08-08 16:17:3190 if (__sync_add_and_fetch(&count(), count_t(-1)) < 0)
Howard Hinnant3e519522010-05-11 19:42:1691 delete [] (str_ - offset);
92}
93
94}
95
Howard Hinnant79710102013-10-04 22:12:5996#if ! defined(_LIBCPP_MSVC)
Daniel Dunbar0a779b92010-09-04 03:15:5197#pragma GCC visibility pop
Howard Hinnant79710102013-10-04 22:12:5998#endif
Howard Hinnant3e519522010-05-11 19:42:1699
100namespace std // purposefully not using versioning namespace
101{
102
103logic_error::logic_error(const string& msg)
104{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13105 __libcpp_nmstr *s = reinterpret_cast<__libcpp_nmstr *>(&__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00106 ::new(s) __libcpp_nmstr(msg.c_str());
Howard Hinnant3e519522010-05-11 19:42:16107}
108
109logic_error::logic_error(const char* msg)
110{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13111 __libcpp_nmstr *s = reinterpret_cast<__libcpp_nmstr *>(&__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00112 ::new(s) __libcpp_nmstr(msg);
Howard Hinnant3e519522010-05-11 19:42:16113}
114
Howard Hinnanta62f2892011-05-26 19:48:01115logic_error::logic_error(const logic_error& le) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16116{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13117 __libcpp_nmstr *s = reinterpret_cast<__libcpp_nmstr *>(&__imp_);
118 const __libcpp_nmstr *s2 = reinterpret_cast<const __libcpp_nmstr *>(&le.__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00119 ::new(s) __libcpp_nmstr(*s2);
Howard Hinnant3e519522010-05-11 19:42:16120}
121
122logic_error&
Howard Hinnanta62f2892011-05-26 19:48:01123logic_error::operator=(const logic_error& le) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16124{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13125 __libcpp_nmstr *s1 = reinterpret_cast<__libcpp_nmstr *>(&__imp_);
126 const __libcpp_nmstr *s2 = reinterpret_cast<const __libcpp_nmstr *>(&le.__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00127 *s1 = *s2;
Howard Hinnant3e519522010-05-11 19:42:16128 return *this;
129}
130
Peter Collingbourne26dd09e2013-10-06 22:13:19131#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX)
Howard Hinnantf95d9f02012-02-17 19:24:42132
Howard Hinnanta62f2892011-05-26 19:48:01133logic_error::~logic_error() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16134{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13135 __libcpp_nmstr *s = reinterpret_cast<__libcpp_nmstr *>(&__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00136 s->~__libcpp_nmstr();
Howard Hinnant3e519522010-05-11 19:42:16137}
138
139const char*
Howard Hinnanta62f2892011-05-26 19:48:01140logic_error::what() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16141{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13142 const __libcpp_nmstr *s = reinterpret_cast<const __libcpp_nmstr *>(&__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00143 return s->c_str();
Howard Hinnant3e519522010-05-11 19:42:16144}
145
Howard Hinnantf95d9f02012-02-17 19:24:42146#endif
147
Howard Hinnant3e519522010-05-11 19:42:16148runtime_error::runtime_error(const string& msg)
149{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13150 __libcpp_nmstr *s = reinterpret_cast<__libcpp_nmstr *>(&__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00151 ::new(s) __libcpp_nmstr(msg.c_str());
Howard Hinnant3e519522010-05-11 19:42:16152}
153
154runtime_error::runtime_error(const char* msg)
155{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13156 __libcpp_nmstr *s = reinterpret_cast<__libcpp_nmstr *>(&__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00157 ::new(s) __libcpp_nmstr(msg);
Howard Hinnant3e519522010-05-11 19:42:16158}
159
Howard Hinnanta62f2892011-05-26 19:48:01160runtime_error::runtime_error(const runtime_error& le) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16161{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13162 __libcpp_nmstr *s = reinterpret_cast<__libcpp_nmstr *>(&__imp_);
163 const __libcpp_nmstr *s2 = reinterpret_cast<const __libcpp_nmstr *>(&le.__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00164 ::new(s) __libcpp_nmstr(*s2);
Howard Hinnant3e519522010-05-11 19:42:16165}
166
167runtime_error&
Howard Hinnanta62f2892011-05-26 19:48:01168runtime_error::operator=(const runtime_error& le) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16169{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13170 __libcpp_nmstr *s1 = reinterpret_cast<__libcpp_nmstr *>(&__imp_);
171 const __libcpp_nmstr *s2 = reinterpret_cast<const __libcpp_nmstr *>(&le.__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00172 *s1 = *s2;
Howard Hinnant3e519522010-05-11 19:42:16173 return *this;
174}
175
Peter Collingbourne26dd09e2013-10-06 22:13:19176#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX)
Howard Hinnantf95d9f02012-02-17 19:24:42177
Howard Hinnanta62f2892011-05-26 19:48:01178runtime_error::~runtime_error() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16179{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13180 __libcpp_nmstr *s = reinterpret_cast<__libcpp_nmstr *>(&__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00181 s->~__libcpp_nmstr();
Howard Hinnant3e519522010-05-11 19:42:16182}
183
184const char*
Howard Hinnanta62f2892011-05-26 19:48:01185runtime_error::what() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16186{
Joerg Sonnenberger70d4ba72014-01-07 19:21:13187 const __libcpp_nmstr *s = reinterpret_cast<const __libcpp_nmstr *>(&__imp_);
Joerg Sonnenberger634b9dd2014-01-04 17:43:00188 return s->c_str();
Howard Hinnant3e519522010-05-11 19:42:16189}
190
Howard Hinnanta62f2892011-05-26 19:48:01191domain_error::~domain_error() _NOEXCEPT {}
192invalid_argument::~invalid_argument() _NOEXCEPT {}
193length_error::~length_error() _NOEXCEPT {}
194out_of_range::~out_of_range() _NOEXCEPT {}
Howard Hinnant3e519522010-05-11 19:42:16195
Howard Hinnanta62f2892011-05-26 19:48:01196range_error::~range_error() _NOEXCEPT {}
197overflow_error::~overflow_error() _NOEXCEPT {}
198underflow_error::~underflow_error() _NOEXCEPT {}
Howard Hinnant3e519522010-05-11 19:42:16199
Howard Hinnantf95d9f02012-02-17 19:24:42200#endif
201
Howard Hinnant3e519522010-05-11 19:42:16202} // std