166f3ac9dSRichard Smith // RUN: %clang_cc1 -std=c++11 %s -verify -fcxx-exceptions
266f3ac9dSRichard Smith
366f3ac9dSRichard Smith // We permit overriding an implicit exception specification with an explicit one
466f3ac9dSRichard Smith // as an extension, for compatibility with existing code.
566f3ac9dSRichard Smith
666f3ac9dSRichard Smith struct S {
766f3ac9dSRichard Smith void a(); // expected-note {{here}}
866f3ac9dSRichard Smith ~S(); // expected-note {{here}}
966f3ac9dSRichard Smith void operator delete(void*); // expected-note {{here}}
1066f3ac9dSRichard Smith };
1166f3ac9dSRichard Smith
a()1266f3ac9dSRichard Smith void S::a() noexcept {} // expected-error {{does not match previous}}
~S()1366f3ac9dSRichard Smith S::~S() noexcept {} // expected-warning {{function previously declared with an implicit exception specification redeclared with an explicit exception specification}}
operator delete(void *)1466f3ac9dSRichard Smith void S::operator delete(void*) noexcept {} // expected-warning {{function previously declared with an implicit exception specification redeclared with an explicit exception specification}}
1566f3ac9dSRichard Smith
1666f3ac9dSRichard Smith struct T {
1766f3ac9dSRichard Smith void a() noexcept; // expected-note {{here}}
1866f3ac9dSRichard Smith ~T() noexcept; // expected-note {{here}}
1966f3ac9dSRichard Smith void operator delete(void*) noexcept; // expected-note {{here}}
2066f3ac9dSRichard Smith };
2166f3ac9dSRichard Smith
a()22*a91de375SRichard Smith void T::a() {} // expected-error {{missing exception specification 'noexcept'}}
~T()2366f3ac9dSRichard Smith T::~T() {} // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}}
operator delete(void *)2466f3ac9dSRichard Smith void T::operator delete(void*) {} // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}}
2566f3ac9dSRichard Smith
2666f3ac9dSRichard Smith
2766f3ac9dSRichard Smith // The extension does not extend to function templates.
2866f3ac9dSRichard Smith
2966f3ac9dSRichard Smith template<typename T> struct U {
3066f3ac9dSRichard Smith T t;
3166f3ac9dSRichard Smith ~U(); // expected-note {{here}}
3266f3ac9dSRichard Smith void operator delete(void*); // expected-note {{here}}
3366f3ac9dSRichard Smith };
3466f3ac9dSRichard Smith
~U()3566f3ac9dSRichard Smith template<typename T> U<T>::~U() noexcept(true) {} // expected-error {{exception specification in declaration does not match previous declaration}}
operator delete(void *)3666f3ac9dSRichard Smith template<typename T> void U<T>::operator delete(void*) noexcept(false) {} // expected-error {{exception specification in declaration does not match previous declaration}}
37e934af8eSEli Friedman
38e934af8eSEli Friedman
39e934af8eSEli Friedman // Make sure this restriction interacts properly with __attribute__((noreturn))
40e934af8eSEli Friedman void __attribute__ ((__noreturn__)) PR17110(int status) throw();
41e934af8eSEli Friedman void PR17110(int status) throw();
42