1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -std=c++11 %s -verify -fcxx-exceptions
2*f4a2713aSLionel Sambuc
3*f4a2713aSLionel Sambuc // We permit overriding an implicit exception specification with an explicit one
4*f4a2713aSLionel Sambuc // as an extension, for compatibility with existing code.
5*f4a2713aSLionel Sambuc
6*f4a2713aSLionel Sambuc struct S {
7*f4a2713aSLionel Sambuc void a(); // expected-note {{here}}
8*f4a2713aSLionel Sambuc ~S(); // expected-note {{here}}
9*f4a2713aSLionel Sambuc void operator delete(void*); // expected-note {{here}}
10*f4a2713aSLionel Sambuc };
11*f4a2713aSLionel Sambuc
a()12*f4a2713aSLionel Sambuc void S::a() noexcept {} // expected-error {{does not match previous}}
~S()13*f4a2713aSLionel Sambuc S::~S() noexcept {} // expected-warning {{function previously declared with an implicit exception specification redeclared with an explicit exception specification}}
operator delete(void *)14*f4a2713aSLionel Sambuc void S::operator delete(void*) noexcept {} // expected-warning {{function previously declared with an implicit exception specification redeclared with an explicit exception specification}}
15*f4a2713aSLionel Sambuc
16*f4a2713aSLionel Sambuc struct T {
17*f4a2713aSLionel Sambuc void a() noexcept; // expected-note {{here}}
18*f4a2713aSLionel Sambuc ~T() noexcept; // expected-note {{here}}
19*f4a2713aSLionel Sambuc void operator delete(void*) noexcept; // expected-note {{here}}
20*f4a2713aSLionel Sambuc };
21*f4a2713aSLionel Sambuc
a()22*f4a2713aSLionel Sambuc void T::a() {} // expected-warning {{missing exception specification 'noexcept'}}
~T()23*f4a2713aSLionel Sambuc T::~T() {} // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}}
operator delete(void *)24*f4a2713aSLionel Sambuc void T::operator delete(void*) {} // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}}
25*f4a2713aSLionel Sambuc
26*f4a2713aSLionel Sambuc
27*f4a2713aSLionel Sambuc // The extension does not extend to function templates.
28*f4a2713aSLionel Sambuc
29*f4a2713aSLionel Sambuc template<typename T> struct U {
30*f4a2713aSLionel Sambuc T t;
31*f4a2713aSLionel Sambuc ~U(); // expected-note {{here}}
32*f4a2713aSLionel Sambuc void operator delete(void*); // expected-note {{here}}
33*f4a2713aSLionel Sambuc };
34*f4a2713aSLionel Sambuc
~U()35*f4a2713aSLionel Sambuc template<typename T> U<T>::~U() noexcept(true) {} // expected-error {{exception specification in declaration does not match previous declaration}}
operator delete(void *)36*f4a2713aSLionel Sambuc template<typename T> void U<T>::operator delete(void*) noexcept(false) {} // expected-error {{exception specification in declaration does not match previous declaration}}
37*f4a2713aSLionel Sambuc
38*f4a2713aSLionel Sambuc
39*f4a2713aSLionel Sambuc // Make sure this restriction interacts properly with __attribute__((noreturn))
40*f4a2713aSLionel Sambuc void __attribute__ ((__noreturn__)) PR17110(int status) throw();
41*f4a2713aSLionel Sambuc void PR17110(int status) throw();
42