Fix a corner case that involved calling rethrow_if_nested with a type that had a deleted operator&. Added a test to catch this as well. Thanks to Ville for the heads-up.

llvm-svn: 255517
This commit is contained in:
Marshall Clow 2015-12-14 18:01:56 +00:00
parent 280f7101e8
commit 94b5bc4263
3 changed files with 10 additions and 53 deletions

View File

@ -77,57 +77,6 @@ struct _LIBCPP_TYPE_VIS_ONLY less<void>
};
#endif
// addressof
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp*
addressof(_Tp& __x) _NOEXCEPT
{
return (_Tp*)&reinterpret_cast<const volatile char&>(__x);
}
#if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF)
// Objective-C++ Automatic Reference Counting uses qualified pointers
// that require special addressof() signatures. When
// _LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF is defined, the compiler
// itself is providing these definitions. Otherwise, we provide them.
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
__strong _Tp*
addressof(__strong _Tp& __x) _NOEXCEPT
{
return &__x;
}
#ifdef _LIBCPP_HAS_OBJC_ARC_WEAK
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
__weak _Tp*
addressof(__weak _Tp& __x) _NOEXCEPT
{
return &__x;
}
#endif
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
__autoreleasing _Tp*
addressof(__autoreleasing _Tp& __x) _NOEXCEPT
{
return &__x;
}
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
__unsafe_unretained _Tp*
addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT
{
return &__x;
}
#endif
// __weak_result_type
template <class _Tp>

View File

@ -235,7 +235,7 @@ rethrow_if_nested(const _Ep& __e, typename enable_if<
is_polymorphic<_Ep>::value
>::type* = 0)
{
const nested_exception* __nep = dynamic_cast<const nested_exception*>(&__e);
const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e));
if (__nep)
__nep->rethrow_nested();
}

View File

@ -37,6 +37,13 @@ public:
B(const B& b) : A(b) {}
};
class C
{
public:
virtual ~C() {}
C * operator&() const { assert(false); } // should not be called
};
int main()
{
{
@ -79,7 +86,7 @@ int main()
{
try
{
std::rethrow_if_nested(1);
std::rethrow_if_nested(C());
assert(true);
}
catch (...)
@ -87,4 +94,5 @@ int main()
assert(false);
}
}
}