diff --git a/include/exception b/include/exception index 600b54838..51e83136b 100644 --- a/include/exception +++ b/include/exception @@ -211,19 +211,19 @@ template inline void rethrow_if_nested(const _E& __e, typename enable_if< - !is_same<_E, nested_exception>::value && - is_convertible<_E*, nested_exception*>::value + is_polymorphic<_E>::value >::type* = 0) { - static_cast(__e).rethrow_nested(); + const nested_exception* __nep = dynamic_cast(&__e); + if (__nep) + __nep->rethrow_nested(); } template inline void rethrow_if_nested(const _E& __e, typename enable_if< - is_same<_E, nested_exception>::value || - !is_convertible<_E*, nested_exception*>::value + !is_polymorphic<_E>::value >::type* = 0) { } diff --git a/test/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp b/test/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp index c3f0222e0..fe0c2a07a 100644 --- a/test/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp +++ b/test/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp @@ -22,19 +22,18 @@ class A int data_; public: explicit A(int data) : data_(data) {} + virtual ~A() {} friend bool operator==(const A& x, const A& y) {return x.data_ == y.data_;} }; class B - : public std::nested_exception + : public std::nested_exception, + public A { - int data_; public: - explicit B(int data) : data_(data) {} - B(const B& b) : data_(b.data_) {} - - friend bool operator==(const B& x, const B& y) {return x.data_ == y.data_;} + explicit B(int data) : A(data) {} + B(const B& b) : A(b) {} }; int main() @@ -56,18 +55,35 @@ int main() { throw B(5); } - catch (const B& b0) + catch (const B& b) { try { - B b = b0; - std::rethrow_if_nested(b); - assert(false); + throw b; } - catch (const B& b) + catch (const A& a) { - assert(b == B(5)); + try + { + std::rethrow_if_nested(a); + assert(false); + } + catch (const B& b) + { + assert(b == B(5)); + } } } } + { + try + { + std::rethrow_if_nested(1); + assert(true); + } + catch (...) + { + assert(false); + } + } }