blob: b516b0ca68b34a4a09c00b88bab0eb8394948de5 [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"
Howard Hinnantf95d9f02012-02-17 19:24:4218#include <cxxabi.h>
Howard Hinnant3e519522010-05-11 19:42:1619
20// Note: optimize for size
21
22#pragma GCC visibility push(hidden)
23
24namespace
25{
26
27class __libcpp_nmstr
28{
29private:
30 const char* str_;
31
32 typedef std::size_t unused_t;
33 typedef std::int32_t count_t;
34
35 static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) +
36 sizeof(count_t));
37
Howard Hinnanta62f2892011-05-26 19:48:0138 count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));}
Howard Hinnant3e519522010-05-11 19:42:1639public:
40 explicit __libcpp_nmstr(const char* msg);
41 __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW;
42 __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW;
43 ~__libcpp_nmstr() _LIBCPP_CANTTHROW;
Howard Hinnanta62f2892011-05-26 19:48:0144 const char* c_str() const _NOEXCEPT {return str_;}
Howard Hinnant3e519522010-05-11 19:42:1645};
46
47__libcpp_nmstr::__libcpp_nmstr(const char* msg)
48{
49 std::size_t len = strlen(msg);
50 str_ = new char[len + 1 + offset];
51 unused_t* c = (unused_t*)str_;
52 c[0] = c[1] = len;
53 str_ += offset;
54 count() = 0;
55 std::strcpy(const_cast<char*>(c_str()), msg);
56}
57
58inline
59__libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s)
60 : str_(s.str_)
61{
Howard Hinnant128ba712010-05-24 17:49:4162 __sync_add_and_fetch(&count(), 1);
Howard Hinnant3e519522010-05-11 19:42:1663}
64
65__libcpp_nmstr&
66__libcpp_nmstr::operator=(const __libcpp_nmstr& s)
67{
68 const char* p = str_;
69 str_ = s.str_;
Howard Hinnant128ba712010-05-24 17:49:4170 __sync_add_and_fetch(&count(), 1);
71 if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), -1) < 0)
Howard Hinnant3e519522010-05-11 19:42:1672 delete [] (p-offset);
73 return *this;
74}
75
76inline
77__libcpp_nmstr::~__libcpp_nmstr()
78{
Howard Hinnant128ba712010-05-24 17:49:4179 if (__sync_add_and_fetch(&count(), -1) < 0)
Howard Hinnant3e519522010-05-11 19:42:1680 delete [] (str_ - offset);
81}
82
83}
84
Daniel Dunbar0a779b92010-09-04 03:15:5185#pragma GCC visibility pop
Howard Hinnant3e519522010-05-11 19:42:1686
87namespace std // purposefully not using versioning namespace
88{
89
90logic_error::logic_error(const string& msg)
91{
92 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
93 ::new(&s) __libcpp_nmstr(msg.c_str());
94}
95
96logic_error::logic_error(const char* msg)
97{
98 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
99 ::new(&s) __libcpp_nmstr(msg);
100}
101
Howard Hinnanta62f2892011-05-26 19:48:01102logic_error::logic_error(const logic_error& le) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16103{
104 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
105 ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_);
106}
107
108logic_error&
Howard Hinnanta62f2892011-05-26 19:48:01109logic_error::operator=(const logic_error& le) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16110{
111 __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_;
112 const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_;
113 s1 = s2;
114 return *this;
115}
116
Howard Hinnantf95d9f02012-02-17 19:24:42117#ifndef _LIBCPPABI_VERSION
118
Howard Hinnanta62f2892011-05-26 19:48:01119logic_error::~logic_error() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16120{
121 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
122 s.~__libcpp_nmstr();
123}
124
125const char*
Howard Hinnanta62f2892011-05-26 19:48:01126logic_error::what() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16127{
128 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
129 return s.c_str();
130}
131
Howard Hinnantf95d9f02012-02-17 19:24:42132#endif
133
Howard Hinnant3e519522010-05-11 19:42:16134runtime_error::runtime_error(const string& msg)
135{
136 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
137 ::new(&s) __libcpp_nmstr(msg.c_str());
138}
139
140runtime_error::runtime_error(const char* msg)
141{
142 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
143 ::new(&s) __libcpp_nmstr(msg);
144}
145
Howard Hinnanta62f2892011-05-26 19:48:01146runtime_error::runtime_error(const runtime_error& le) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16147{
148 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
149 ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_);
150}
151
152runtime_error&
Howard Hinnanta62f2892011-05-26 19:48:01153runtime_error::operator=(const runtime_error& le) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16154{
155 __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_;
156 const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_;
157 s1 = s2;
158 return *this;
159}
160
Howard Hinnantf95d9f02012-02-17 19:24:42161#ifndef _LIBCPPABI_VERSION
162
Howard Hinnanta62f2892011-05-26 19:48:01163runtime_error::~runtime_error() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16164{
165 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
166 s.~__libcpp_nmstr();
167}
168
169const char*
Howard Hinnanta62f2892011-05-26 19:48:01170runtime_error::what() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16171{
172 __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_;
173 return s.c_str();
174}
175
Howard Hinnanta62f2892011-05-26 19:48:01176domain_error::~domain_error() _NOEXCEPT {}
177invalid_argument::~invalid_argument() _NOEXCEPT {}
178length_error::~length_error() _NOEXCEPT {}
179out_of_range::~out_of_range() _NOEXCEPT {}
Howard Hinnant3e519522010-05-11 19:42:16180
Howard Hinnanta62f2892011-05-26 19:48:01181range_error::~range_error() _NOEXCEPT {}
182overflow_error::~overflow_error() _NOEXCEPT {}
183underflow_error::~underflow_error() _NOEXCEPT {}
Howard Hinnant3e519522010-05-11 19:42:16184
Howard Hinnantf95d9f02012-02-17 19:24:42185#endif
186
Howard Hinnant3e519522010-05-11 19:42:16187} // std