diff options
| author | Eric Fiselier <eric@efcs.ca> | 2019-03-06 20:31:57 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2019-03-06 20:31:57 +0000 |
| commit | 2710d8e105a683656cdaa825b6c0af46ae25f8ae (patch) | |
| tree | a4895b5f1582ed0ca4b11f69866d347e545db307 /libcxx/include/stdexcept | |
| parent | 5ced5961984b457bba23e0285a57ad12eb2d781b (diff) | |
| download | bcm5719-llvm-2710d8e105a683656cdaa825b6c0af46ae25f8ae.tar.gz bcm5719-llvm-2710d8e105a683656cdaa825b6c0af46ae25f8ae.zip | |
Fix ABI compatibility of `<stdexcept>` with VCRuntime.
Summary:
Currently, libc++'s `<stdexcept>` doesn't play nice with `vcruntime`. Specifically:
* `logic_error` and `runtime_error` have a different layout.
* libc++'s `logic_error` and `runtime_error` override `what()` but `vcruntime` does not.
* `vcruntime` uses weak vtables for `<stdexcept>` types.
* libc++'s `<stdexcept>` constructors and assignment operators may have different manglings than `vcruntimes`.
This patch makes libc++'s declarations in `<stdexcept>` match those provided by MSVC's STL as closely as possible.
If MSVC doesn't declare a special member, then neither do we. This ensures that the implicit definitions have the same linkage, visibility, triviality, and noexcept-ness.
Reviewers: thomasanderson, ldionne, smeenai
Reviewed By: thomasanderson
Subscribers: jdoerfert, libcxx-commits
Differential Revision: https://reviews.llvm.org/D58945
llvm-svn: 355546
Diffstat (limited to 'libcxx/include/stdexcept')
| -rw-r--r-- | libcxx/include/stdexcept | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/libcxx/include/stdexcept b/libcxx/include/stdexcept index 6eda619b8f4..481f9043c50 100644 --- a/libcxx/include/stdexcept +++ b/libcxx/include/stdexcept @@ -54,6 +54,7 @@ public: _LIBCPP_BEGIN_NAMESPACE_STD +#ifndef _LIBCPP_ABI_VCRUNTIME class _LIBCPP_HIDDEN __libcpp_refstring { const char* __imp_; @@ -67,6 +68,7 @@ public: const char* c_str() const _NOEXCEPT {return __imp_;} }; +#endif // !_LIBCPP_ABI_VCRUNTIME _LIBCPP_END_NAMESPACE_STD @@ -76,6 +78,7 @@ namespace std // purposefully not using versioning namespace class _LIBCPP_EXCEPTION_ABI logic_error : public exception { +#ifndef _LIBCPP_ABI_VCRUNTIME private: _VSTD::__libcpp_refstring __imp_; public: @@ -88,11 +91,17 @@ public: virtual ~logic_error() _NOEXCEPT; virtual const char* what() const _NOEXCEPT; +#else +public: + explicit logic_error(const _VSTD::string&); // Symbol uses versioned std::string + _LIBCPP_INLINE_VISIBILITY explicit logic_error(const char* __s) : exception(__s) {} +#endif }; class _LIBCPP_EXCEPTION_ABI runtime_error : public exception { +#ifndef _LIBCPP_ABI_VCRUNTIME private: _VSTD::__libcpp_refstring __imp_; public: @@ -105,6 +114,11 @@ public: virtual ~runtime_error() _NOEXCEPT; virtual const char* what() const _NOEXCEPT; +#else +public: + explicit runtime_error(const _VSTD::string&); // Symbol uses versioned std::string + _LIBCPP_INLINE_VISIBILITY explicit runtime_error(const char* __s) : exception(__s) {} +#endif // _LIBCPP_ABI_VCRUNTIME }; class _LIBCPP_EXCEPTION_ABI domain_error @@ -114,7 +128,9 @@ public: _LIBCPP_INLINE_VISIBILITY explicit domain_error(const string& __s) : logic_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit domain_error(const char* __s) : logic_error(__s) {} +#ifndef _LIBCPP_ABI_VCRUNTIME virtual ~domain_error() _NOEXCEPT; +#endif }; class _LIBCPP_EXCEPTION_ABI invalid_argument @@ -124,7 +140,9 @@ public: _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const string& __s) : logic_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const char* __s) : logic_error(__s) {} +#ifndef _LIBCPP_ABI_VCRUNTIME virtual ~invalid_argument() _NOEXCEPT; +#endif }; class _LIBCPP_EXCEPTION_ABI length_error @@ -133,8 +151,9 @@ class _LIBCPP_EXCEPTION_ABI length_error public: _LIBCPP_INLINE_VISIBILITY explicit length_error(const string& __s) : logic_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit length_error(const char* __s) : logic_error(__s) {} - +#ifndef _LIBCPP_ABI_VCRUNTIME virtual ~length_error() _NOEXCEPT; +#endif }; class _LIBCPP_EXCEPTION_ABI out_of_range @@ -144,7 +163,9 @@ public: _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const string& __s) : logic_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const char* __s) : logic_error(__s) {} +#ifndef _LIBCPP_ABI_VCRUNTIME virtual ~out_of_range() _NOEXCEPT; +#endif }; class _LIBCPP_EXCEPTION_ABI range_error @@ -154,7 +175,9 @@ public: _LIBCPP_INLINE_VISIBILITY explicit range_error(const string& __s) : runtime_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit range_error(const char* __s) : runtime_error(__s) {} +#ifndef _LIBCPP_ABI_VCRUNTIME virtual ~range_error() _NOEXCEPT; +#endif }; class _LIBCPP_EXCEPTION_ABI overflow_error @@ -164,7 +187,9 @@ public: _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const string& __s) : runtime_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const char* __s) : runtime_error(__s) {} +#ifndef _LIBCPP_ABI_VCRUNTIME virtual ~overflow_error() _NOEXCEPT; +#endif }; class _LIBCPP_EXCEPTION_ABI underflow_error @@ -174,7 +199,9 @@ public: _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const string& __s) : runtime_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const char* __s) : runtime_error(__s) {} +#ifndef _LIBCPP_ABI_VCRUNTIME virtual ~underflow_error() _NOEXCEPT; +#endif }; } // std |

