// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -fms-extensions -Wno-delete-incomplete %s // expected-no-diagnostics #define P(e) static_assert(noexcept(e), "expected nothrow") #define N(e) static_assert(!noexcept(e), "expected throw") #define B(b, e) static_assert(b == noexcept(e), "expectation failed") void simple() { P(0); P(0 + 0); int i; P(i); P(sizeof(0)); P(static_cast<int>(0)); N(throw 0); N((throw 0, 0)); } void nospec(); void allspec() throw(...); void intspec() throw(int); void emptyspec() throw(); void nothrowattr() __attribute__((nothrow)); void noexcept_true() noexcept; void noexcept_false() noexcept(false); void call() { N(nospec()); N(allspec()); N(intspec()); P(emptyspec()); P(nothrowattr()); P(noexcept_true()); N(noexcept_false()); } void (*pnospec)(); void (*pallspec)() throw(...); void (*pintspec)() throw(int); void (*pemptyspec)() throw(); typedef void (*funcptr)(); funcptr returnsptr() throw(); void callptr() { N(pnospec()); N((*pnospec)()); N(pallspec()); N((*pallspec)()); N(pintspec()); N((*pintspec)()); P(pemptyspec()); P((*pemptyspec)()); N(returnsptr()()); } struct S1 { void nospec(); void allspec() throw(...); void intspec() throw(int); void emptyspec() throw(); }; void callmem() { S1 s; N(s.nospec()); N(s.allspec()); N(s.intspec()); P(s.emptyspec()); } void (S1::*mpnospec)(); void (S1::*mpallspec)() throw(...); void (S1::*mpintspec)() throw(int); void (S1::*mpemptyspec)() throw(); void callmemptr() { S1 s; N((s.*mpnospec)()); N((s.*mpallspec)()); N((s.*mpintspec)()); P((s.*mpemptyspec)()); } struct S2 { S2(); S2(int, int) throw(); void operator +(); void operator -() throw(); void operator +(int); void operator -(int) throw(); operator int(); operator float() throw(); }; void *operator new(__typeof__(sizeof(int)) sz, int) throw(); struct IncompleteStruct; struct Bad1 { ~Bad1() throw(int); }; struct Bad2 { void operator delete(void*) throw(int); }; typedef int X; void implicits() { N(new int); P(new (0) int); P(delete (int*)0); P(delete (IncompleteStruct*)0); N(delete (Bad1*)0); N(delete (Bad2*)0); N(S2()); P(S2(0, 0)); S2 s; N(+s); P(-s); N(s + 0); P(s - 0); N(static_cast<int>(s)); P(static_cast<float>(s)); N(Bad1()); P(X().~X()); } struct V { virtual ~V() throw(); }; struct D : V {}; void dyncast() { V *pv = 0; D *pd = 0; P(dynamic_cast<V&>(*pd)); P(dynamic_cast<V*>(pd)); N(dynamic_cast<D&>(*pv)); P(dynamic_cast<D*>(pv)); } namespace std { struct type_info {}; } void idtype() { P(typeid(V)); P(typeid((V*)0)); P(typeid(*(S1*)0)); N(typeid(*(V*)0)); } void uneval() { P(sizeof(typeid(*(V*)0))); P(typeid(typeid(*(V*)0))); } struct G1 {}; struct G2 { int i; }; struct G3 { S2 s; }; void gencon() { P(G1()); P(G2()); N(G3()); } template <class T> void f(T&&) noexcept; template <typename T, bool b> void late() { B(b, typeid(*(T*)0)); B(b, T(1)); B(b, static_cast<T>(S2(0, 0))); B(b, S1() + T()); P(f(T())); P(new (0) T); P(delete (T*)0); } struct S3 { virtual ~S3() throw(); S3() throw(); explicit S3(int); S3(const S2&); }; template <class T> T&& f2() noexcept; template <typename T> void late2() { P(dynamic_cast<S3&>(f2<T&>())); } void operator +(const S1&, float) throw(); void operator +(const S1&, const S3&); void tlate() { late<float, true>(); late<S3, false>(); late2<S3>(); }