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