
Delayed exception specification checking for defaulted members and virtual destructors are both susceptible to mutation during iteration so we need to swap and process the worklists. This resolves both accepts-invalid and rejects-valid issues and moreover fixes potential invalid memory access as the contents of the vectors change during iteration and recursive template instantiation. Checking can be further delayed where parent classes aren't yet fully defined. This patch adds two assertions at end of TU to ensure no specs are left unchecked as was happenning before the fix, plus a test case from Marshall Clow for the defaulted member crash extracted from the libcxx headers. Reviewed by Richard Smith. llvm-svn: 192947
31 lines
771 B
C++
31 lines
771 B
C++
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
|
|
// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -DCXX_EXCEPTIONS -fsyntax-only -verify %s
|
|
|
|
template <class _Tp> struct is_nothrow_move_constructible {
|
|
static const bool value = false;
|
|
};
|
|
|
|
template <class _Tp>
|
|
class allocator;
|
|
|
|
template <>
|
|
class allocator<char> {};
|
|
|
|
template <class _Allocator>
|
|
class basic_string {
|
|
typedef _Allocator allocator_type;
|
|
basic_string(basic_string &&__str)
|
|
noexcept(is_nothrow_move_constructible<allocator_type>::value);
|
|
};
|
|
|
|
class Foo {
|
|
Foo(Foo &&) noexcept = default;
|
|
#ifdef CXX_EXCEPTIONS
|
|
// expected-error@-2 {{does not match the calculated}}
|
|
#else
|
|
// expected-no-diagnostics
|
|
#endif
|
|
Foo &operator=(Foo &&) noexcept = default;
|
|
basic_string<allocator<char> > vectorFoo_;
|
|
};
|